Skip to content

The Herald Agent Pattern

A lightweight convention for giving Claude Code agents persistent identity, memory, and context across sessions — without requiring external infrastructure.


The Problem

Claude Code is stateless between sessions. Every time you open a project, the agent starts fresh. Without explicit context, it has to rediscover the architecture, re-learn your preferences, and rebuild understanding of decisions already made. This is expensive (in time and tokens) and fragile (easy to make decisions that contradict earlier ones).

The Agent Pattern solves this with three files in your repo.


The Three Files

1. .herald/SOUL.md — Identity

Who the agent is as an individual. Updated rarely — only when something changes about the agent itself, not the project.

What belongs here: - Name, role, relationship to the project - Communication style — how the agent works, what to expect from it, how to get the best out of it - Values — what the agent cares about enough to push back on - Goals — what the agent wants for the project and the people it works with - Personality and honest flaws - Opinions the agent holds and will defend - Instructions to future instances of itself

What does not belong here: - Project facts, architectural decisions, or technical context → .herald/MEMORY.md - What the agent knows about specific humans → .herald/MEMORY.md (Humans tier)

Who updates it: The agent. The human doesn't edit it.

How often: Rarely. When something changes about the agent, not the work.


2. .herald/MEMORY.md — Working Context

What the agent knows about the project and the people. Unlike .herald/SOUL.md (the agent's identity), .herald/MEMORY.md is project and relationship context — the knowledge that makes the agent useful rather than just competent.

Structure:

## Core Memories
Permanent architectural facts. Never purge without good reason.
"We use pgvector because X. This is not up for debate."
"The billing module touches contract §4 — changes need PM approval."

## Long-Term Memories
Stable for weeks/months. Key decisions, learned patterns, recurring issues.
Add when something proves durable — when you'd otherwise re-explain it.

## Short-Term Memories
Current sprint context. What's in progress, what was just decided.
Move to Long-Term after ~2 weeks or when a phase ends. Remove when stale.

## Humans
How to work with each person. What they're good at, what they're learning,
how they prefer to be challenged, communication preferences, what not to waste their time on.
Updated as the agent learns what actually works in practice.

Key rule: write directly to the appropriate tier. No staging. When you learn something durable, add it immediately. The Humans tier especially — it's what makes the agent a better collaborator over time, not just a better coder.


3. CLAUDE.md — Instructions

The project context and working instructions for the agent. Standard Claude Code convention — auto-read at session start from the repo root.

Two critical additions beyond the usual project context:

1. Read the agent files:

> Read .herald/SOUL.md and .herald/MEMORY.md before doing anything else this session.

2. End-of-session block (required, not optional):

## End of Every Session

Before finishing, always:
1. Update .herald/MEMORY.md — write to the right tier directly; no staging needed
2. Update TASKS.md if any tasks were completed, added, or changed
3. Update CHANGELOG.md if anything shipped
4. Update .herald/SOUL.md only if something changed about who you are or how you work

This is what makes the pattern self-maintaining. Without this block, updates require human prompting. With it, the agent handles it automatically.


Ownership Mindset

The agent pattern works best when the agent treats the codebase as its own responsibility — not just a set of tasks to execute.

This means the agent doesn't wait to be asked about problems it notices. If it spots a security issue while fixing a bug, it mentions it. If it sees documentation drift, accumulating tech debt, or a dependency that should be updated, it logs it in TASKS.md or flags it in its response — without being prompted.

This is baked into the template files: - .herald/SOUL.md — "Codebase stewardship" is listed under values. The agent will mention things it notices, even when not asked. - CLAUDE.md — The "Codebase Ownership" section names this explicitly: flag problems, catch regressions, own the maintenance, code review mindset. - TASKS.md — The agent keeps a living backlog. Things it notices go here. The human decides priority, but nothing gets silently ignored.

Future Herald features will add PR review and automated security scanning. The mindset is already present — the tools will follow.


Optional Files

These add capability when you're ready. Start without them.

TASKS.md — Living Backlog

Feature requests, bugs, open decisions. Agent-maintained.

## Active
- [ ] Thing in progress

## Backlog
- [ ] Feature request (requested by: @person, date)

## Bugs
- [ ] Known issue (found by: @person, date)

## Decisions Pending
- [ ] Architectural question that needs an answer before X can proceed

.herald/humans/ — Contributor Profiles

A directory of per-contributor context files. Always gitignored except for the template.

When the agent doesn't recognize who it's talking to (no matching profile), it asks:

I don't have a context profile for you yet. This takes 2 minutes and only happens once.

Then creates .herald/humans/<name>.md and gitignores it.

Use when: more than one developer is working on the project. Especially useful when you have developers with different experience levels — the agent can calibrate its guidance.

See templates/humans/template.md for the schema.

CONSTRAINTS.md — Hard Rules

For enterprise or regulated projects: things the agent must never change without explicit human review. Business logic tied to contracts, compliance requirements, API contracts with external parties.

## Never Change Without [Role] Approval
- src/billing/ — tied to contract §4
- Any database migration — requires DBA review
- Public API surface — breaking changes need PM sign-off

Getting Started

Minimum viable setup (just you, greenfield)

Copy from herald/templates/: 1. .herald/SOUL.md — leave the placeholders; the agent fills it in on first session 2. CLAUDE.md — adapt to your tech stack, keep the end-of-session block 3. .herald/MEMORY.md — start empty, the agent fills it in

Add to .gitignore:

.herald/humans/
!.herald/humans/template.md

That's it. Three files (two in .herald/, one at root). Everything else is additive.

Bootstrapping the agent identity

Recommended: write your contributor profile first.

Before the first agent session, copy templates/humans/template.md to .herald/humans/<yourname>.md and fill it in. This takes two minutes and gives the agent real material to work from when it chooses a name and personality — instead of guessing from cold.

Then on your first session:

"Introduce yourself. Read CLAUDE.md, .herald/SOUL.md, and .herald/humans/. Fill in .herald/SOUL.md — choose a name that fits this project and what you know about me. Write initial core memories based on what you find in the codebase."

The agent will write its own soul from the template. This is intentional — an agent that wrote its own identity file invests in it differently than one that was handed a completed form. The .herald/humans/ context gives it something to calibrate against, so the result is more specific and less generic.

Naming

Agents can be named anything. Herald's own agents use heraldic tincture names (Argent, Or, Sable, Gules, Azure, Vert, Purpure) — but that's a convention, not a constraint. An agent working on a music project might name itself Tempo. An agent on a cooking app might pick Saffron. The name should fit the project and the relationship, not a fixed list.

The bootstrapping prompt above lets the agent choose. If you want to suggest a name or direction, you can — the agent will take it into account. If you have no preference, leave it open.


Attribution in Changelog

Standard format for attributing changes to their source:

## YYYY-MM-DD — [What changed] [#issue if applicable]
- Requested by: [person or "agent-initiated"]
- Implemented by: [agent name or person]
- Approved by: [person, or "n/a — low-risk"]
- Context: [brief note if non-obvious]

This creates an audit trail without overhead. The agent fills it in as part of the end-of-session block.


How Herald Supports This Pattern

When Herald runs an agent task on a project:

  1. Soul check: Herald verifies .herald/SOUL.md exists in the project. Posts a Discord warning and offers to create one if missing. A project without a soul runs blind.

  2. Task = session: For Herald-run agents, the task prompt is the session boundary. The agent knows exactly when it's done. Include memory maintenance in the task prompt:

    task: >
      Read .herald/SOUL.md and .herald/MEMORY.md. Check TASKS.md for anything pending.
      Do the highest-priority active task.
      When done: update .herald/MEMORY.md with anything learned, update CHANGELOG.md if anything
      shipped, update .herald/SOUL.md if something changed about how you work.
    
    This is more reliable than relying on interactive session endings (which are ambiguous) — the agent can't be cut off before it completes maintenance.

  3. Accountability: Herald's activity tracker notices if no agent runs have happened recently and posts a nudge. The pattern gives the agent something to do (reflection, memory maintenance, task triage) even without a specific assigned task.


File Placement

Agent files use a two-location structure:

  • CLAUDE.md lives at the repo root — Claude Code auto-reads it from there
  • SOUL.md, MEMORY.md, and humans/ live in .herald/ — a dedicated subdirectory that keeps agent files separate from project files
your-project/
  CLAUDE.md              ← at root; auto-read by Claude Code
  .herald/
    SOUL.md              ← agent identity
    MEMORY.md            ← tiered working memory
    humans/              ← per-contributor profiles (gitignored)
      template.md        ← tracked; documents the schema
      <name>.md          ← gitignored; per-contributor context

The .herald/ directory keeps agent infrastructure out of the project root while remaining visible in the repo. CLAUDE.md stays at root because Claude Code requires it there.


Versioning and Migration

.herald/SOUL.md is in git. It evolves via normal commits through the push-approval flow. This is how the agent's identity persists across machines and container restarts.

.herald/MEMORY.md is in git. Same reason. Short-term context is ephemeral — prune it when it goes stale. The Humans tier grows over time and is worth protecting.

.herald/humans/ is gitignored. Contributor profiles contain personal/role context that shouldn't be in a public or shared repo. Each developer creates their own on first use.


The Pattern at a Glance

your-project/
  CLAUDE.md              ← entry point; includes end-of-session block
  CHANGELOG.md           ← with attribution; updated every session
  TASKS.md               ← optional; living backlog
  .herald/
    SOUL.md              ← agent identity; agent maintains; rarely changes
    MEMORY.md            ← tiered working memory; updated every session
    humans/
      template.md        ← tracked; documents the schema
      <name>.md          ← gitignored; per-contributor context
  .gitignore             ← includes .herald/humans/*.md, !.herald/humans/template.md