Heartwood
A persistent agent identity — a HEARTWOOD.md persona composed into the frozen prefix of the system prompt, the same way a hosted app loads identity from a database.
Heartwood is the agent's persistent identity — a persona that
leads every turn's system prompt. A standalone @pleach/core
consumer gives its agent a stable voice from a HEARTWOOD.md file
(the "SOUL.md" pattern); a hosted app loads the same section from a
database. Either way the identity is composed into the frozen
prefix — the head of the system prompt that does not change
turn-to-turn — so it sits inside the cacheable region rather than
rotating the cache key.
Ships from the @pleach/core/quickstart barrel:
createFileHeartwoodLoader, createHeartwoodPlugin,
formatHeartwoodSection, and the HeartwoodSource type.
The file loader
createFileHeartwoodLoader() reads ./HEARTWOOD.md and formats it
into an identity section. Point it elsewhere with path, and cap
the working size with maxChars (default 2000).
import { createPleachAgent } from "@pleach/core";
import { createFileHeartwoodLoader } from "@pleach/core/quickstart";
const agent = createPleachAgent({
context: process.env.OPENROUTER_API_KEY,
heartwoodSource: createFileHeartwoodLoader(), // reads ./HEARTWOOD.md
});A HEARTWOOD.md is plain markdown. An optional ## Voice & Tone
heading splits persona from voice; the identity leads and the
voice follows.
You are Atlas, a meticulous research companion. You cite every
claim and never guess at a number you have not seen.
## Voice & Tone
Terse, precise, no hedging.The source contract
heartwoodSource is a HeartwoodSource — () => string | null (or
its async form). Return the identity text, or null for "no
identity this run" (which leaves the prompt byte-identical to having
no heartwood at all). createFileHeartwoodLoader is one
implementation; a hosted app passes its own loader that reads a row
from a database.
import type { HeartwoodSource } from "@pleach/core/quickstart";
const fromDb: HeartwoodSource = () => loadPersonaRowSync(userId)?.identity ?? null;| Field | Type | Notes |
|---|---|---|
heartwoodSource | HeartwoodSource | undefined | () => string | null (sync or async). Omit ⇒ no identity section. |
heartwoodMaxChars | number | undefined | Route-level HARD ceiling on the resolved section, default 8000. |
A sync source is resolved once so the first turn already carries the
identity; an async source primes fire-and-forget (the first turn may
miss it, later turns have it). The heartwoodMaxChars ceiling is the
cost backstop for the never-dropped frozen-prefix slot — a loader's
own maxChars below it is honored verbatim, a raw huge source is
bounded here.
As a plugin
Under the façade, createHeartwoodPlugin(source) contributes the
identity through contributeRuntimeAwarePrompts as a prepend, so it
composes ahead of the core baseline and lands at the stable head. Use
it directly when you compose the runtime yourself instead of through
createPleachAgent.
import { createHeartwoodPlugin } from "@pleach/core/quickstart";
const plugin = createHeartwoodPlugin(() => "You are Atlas.");Where to go next
Prompts
The contribution registry the identity section composes through.
Prompt builder
How resolved contributions become the final budgeted system prompt.
Skills
Intent-matched markdown skills, plus on-demand skill bodies via `skill_view`.
Quickstart
The createPleachAgent three-arm façade heartwoodSource plugs into.
Prompt builder
`composeBudgetedPrompt` — the deterministic composer that turns resolved contributions into the final system prompt with quantized budget math.
Model hooks
Two interception points around every provider call — pre-model hooks reshape the request, post-model hooks validate or retry the response. Four hooks ship in the box.