Harvey Fountain Format Specification
Version 1.2 — Multi-model character attribution for Harvey session recordings
Overview
Harvey uses the Fountain screenplay format for
session recordings, stored with .spmd (Harvey-native) or
.fountain (compatible with other tools) extensions.
Fountain provides a plain-text, human-readable, and machine-parseable
format that serves as a lingua franca between Harvey,
Claude Code, and other LLM-based agents.
Why Fountain?
| Requirement | Fountain Solution |
|---|---|
| Human-readable | Plain text, familiar screenplay format |
| Machine-parseable | Strict structure, regex-friendly |
| Version-control friendly | Text files, good diff/merge behavior |
| Multi-participant | Natural character/dialogue model |
| Extensible | Scene descriptions, parenthetical notes |
| Cross-agent compatible | Open format, shared with Claude Code |
File Extensions
| Extension | Created By | Notes |
|---|---|---|
.spmd |
Harvey | Primary format for new recordings |
.fountain |
Any Fountain-compatible tool | Accepted by Harvey for reading |
Character Model
Harvey Fountain sessions treat each participant (human, Harvey agent, or LLM) as a distinct character in a screenplay. Character names follow specific conventions that reveal their identity and role.
Character Types
| Type | Naming Convention | Example | Identity |
|---|---|---|---|
| Human User | ALL-CAPS (matches Author:) |
RSDOIEL | Human participant |
| Harvey Agent | HARVEY | HARVEY | Harvey using local Ollama/Llamafile |
| Routed Ollama | ROUTE_NAME (ALL-CAPS) | PI2, NODE1, JULIE | Remote Ollama via /route add |
| Cloud Model | MODEL_NAME (ALL-CAPS) | MISTRAL, CLAUDE, GEMMA4 | Cloud API or forwarded |
Character Identity Rules
HARVEY represents Harvey when: - Using its locally
configured Ollama backend - Using its locally configured Llamafile
backend - The active model is noted in the scene description:
Model: llama3:latest
ROUTE_NAME represents a remote Ollama instance when:
- Defined via /route add NAME URL (e.g.,
/route add pi2 ollama://192.168.1.2:11434) - Harvey
forwards to it: HARVEY\nForwarding to PI2. - The route
appears as a character: PI2\nResponse...
MODEL_NAME represents a cloud/remote model when: -
User uses @mention:
RSDOIEL\n@mistral explain this - Harvey forwards:
HARVEY\nForwarding to MISTRAL. - Model responds:
MISTRAL\nExplanation... - OR in EXT. scenes (direct
conversation without Harvey)
Character Naming Conventions
| Pattern | Matches | Example |
|---|---|---|
^[A-Z]{2,}$ |
Cloud model names | CLAUDE, MISTRAL, LLAMA3 |
^[A-Z][a-zA-Z0-9_-]*$ |
Mixed case (rare) | Julie (if configured as route) |
^HARVEY$ |
Harvey agent | HARVEY |
| Author name (from title) | Human user | RSDOIEL |
Scene Types
Harvey uses two scene type prefixes from Fountain: INT. (Interior) and EXT. (Exterior). These distinguish where the computation runs — on the local machine or on a remote system.
INT. — Interior Scenes (Local Computation)
The computation runs on the same machine as Harvey. Harvey is the active agent. The scene heading always names HARVEY and the human participant.
Format:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 18:30:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
RSDOIEL
User prompt here...
HARVEY
Harvey's response using the local model.
Use cases: - Harvey responding with its local Ollama/Llamafile model - Agent actions (file writes) - Skill activations - Shell command execution - Session context recall (memory injection at session start)
EXT. — Exterior Scenes (Remote Computation)
The computation runs on a remote system — a remote Ollama instance, a cloud API, or any endpoint reached over the network. Harvey may still appear as the routing intermediary, but the model doing the work is external.
The scene heading names the remote endpoint and the human participant rather than HARVEY. When Harvey routes the request, HARVEY appears in the dialogue as a forwarding character. When the conversation is truly direct (no Harvey involvement), HARVEY is absent.
Format (Harvey routing to remote endpoint):
EXT. PI2 AND RSDOIEL 2026-05-04 18:30:00
Harvey routing to PI2 at ollama://192.168.1.2:11434. Workspace: /home/user/project.
RSDOIEL
@pi2 analyze this data
HARVEY
Forwarding to PI2.
PI2
Remote response...
Format (direct conversation, no Harvey):
EXT. MISTRAL AND RSDOIEL 2026-05-04 18:30:00
MISTRAL and RSDOIEL in direct conversation. Workspace: /home/user/project.
RSDOIEL
Direct prompt to Mistral...
MISTRAL
Mistral's direct response...
Use cases: - Remote Ollama routes (registered via
/route add, e.g. @pi2) - Cloud API calls via
registered routes (e.g. @mistral, @claude) -
Direct API conversations bypassing Harvey
Scene Structure
Title Block (Before FADE IN:)
The title block contains metadata about the session. All fields are
optional except Title: and Author:.
Fields:
| Field | Required | Example | Description |
|---|---|---|---|
Title: |
Yes | Harvey Session |
Session title |
Credit: |
No | Recorded by Harvey |
Recording application |
Author: |
Yes | RSDOIEL |
Human participant (ALL-CAPS) |
Date: |
No | 2026-05-04 18:30:00 |
Session start timestamp |
Draft date: |
No | 2026-05-04 |
Date only |
Characters: |
No | RSDOIEL, HARVEY, MISTRAL |
All characters (summary files only) |
Example:
Title: Harvey Session - Documentation Review
Credit: Recorded by Harvey
Author: RSDOIEL
Date: 2026-05-04 18:30:00
Draft date: 2026-05-04
Characters: RSDOIEL, HARVEY, MISTRAL
FADE IN:
Note: The Characters: field is
typically omitted in streaming sessions (since future
characters are unknown) and added in summary/analysis
files (where all participants are known).
Scene Heading
Format:
(INT|EXT)\. CHARACTER1 AND CHARACTER2 (TALKING|) TIMESTAMP
Regex:
(INT|EXT)\. ([A-Z0-9_-]+) AND ([A-Z0-9_-]+) (TALKING)? (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})
Examples:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 18:30:00
INT. AGENT MODE 2026-05-04 18:35:00
INT. SKILL FOUNTAIN-ANALYSIS 2026-05-04 18:40:00
EXT. MISTRAL AND RSDOIEL 2026-05-04 18:45:00
Scene Description
The scene description appears between the scene heading and the first character/dialogue line. It provides context for the scene.
Required fields: -
Model: <identifier> — The model/route for this
interaction - Workspace: <path> — The workspace
directory
Privacy note:
Workspace:records the absolute path of the user’s local workspace directory. Review.spmdsession files before sharing them externally or committing them to a repository — they contain this path and the full output of any shell commands run during the session.
Optional fields: - Any additional context (e.g.,
“Connected: Ollama (llama3:latest)”) - Parenthetical notes about @mentions:
(@modelname mentioned but does not respond)
Examples:
# Harvey-native (local Ollama)
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
# Routed Ollama
Harvey and RSDOIEL are in chat mode. Model: ollama://192.168.1.2:11434. Workspace: /home/user/project.
# With @mention note
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
(@julie mentioned but does not respond)
Dialogue
Dialogue consists of character names (ALL-CAPS) followed by their lines. Character names must match the names in the scene heading or be introduced via forwarding.
Format:
CHARACTER_NAME
Dialogue line 1
Dialogue line 2
ANOTHER_CHARACTER
Response...
Rules: - Character names are always ALL-CAPS - Blank line separates character from dialogue - Blank line between dialogue blocks - Dialogue wraps naturally (no special formatting needed)
Special Syntax
Forwarding
When Harvey forwards a prompt to another model:
HARVEY
Forwarding to MODEL_NAME.
MODEL_NAME
Response...
@Mention
User can direct prompts to specific models:
RSDOIEL
@mistral explain this code
HARVEY
Forwarding to MISTRAL.
MISTRAL
Explanation...
File Operations (Agent Scenes)
HARVEY
Write path/to/file?
RSDOIEL
yes
[[write: path/to/file — ok]]
[[write: path/to/other — skipped]]
[[write: path/to/error — error: permission denied]]
Status values: ok, skipped,
error: <message>
Tool Call Notes
Notes emitted inside a chat scene for each tool invoked during the turn. They appear between HARVEY’s forwarding line and the model’s reply.
[[tool: name(args) — status]]
[[CHARACTER.tool: name(args) — status]]
Status values: ok,
error: <first line of error>
The CHARACTER.tool: prefix is used when a remote model
invoked the tool (e.g. in a local @mention model-switch scene). Omit args when
the call had none or the args object is empty.
Example:
HARVEY
Forwarding to LLAMA3.
[[tool: read_file({"path":"harvey.go"}) — ok]]
[[tool: run_shell({"cmd":"go build ./..."}) — error: exit 1]]
LLAMA3
There is a compilation error on line 42.
RAG Provenance Notes
Emitted inside the chat scene before the user’s dialogue, when RAG retrieval returned chunks for the turn.
[[rag: N chunks from STORE, top score S.SS]]
Turns where RAG did not fire produce no [[rag:]]
line.
Example:
[[rag: 3 chunks from rag_store.db, top score 0.87]]
RSDOIEL
How do I initialise a Go module?
Context Recall Notes
Emitted in the INT. CONTEXT RECALL scene at session
start (see Scene Types Reference). One note per recalled memory
item.
[[recall: ID (SOURCE) — score S.SS]]
Example:
INT. CONTEXT RECALL 2026-06-24 10:00:01
[[recall: workspace_profile_250928 (workspace_profile) — score 1.00]]
[[recall: tool_use_d55f70 (tool_use) — score 0.75]]
Session End
Every session file must end with:
THE END.
This marker is used by parsers to detect complete sessions.
Model Representation Scenarios
Scenario 1: Harvey Using Local Ollama
Harvey responds directly using its configured local model.
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 18:30:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
RSDOIEL
What is the capital of France?
HARVEY
The capital of France is Paris.
Character: HARVEY (Harvey agent with local model) Model: llama3:latest (from scene description)
Scenario 2: Harvey Routing to Remote Ollama
Harvey routes to a remote Ollama instance registered as a route. The computation runs on the remote machine, so the scene is EXT.
EXT. PI2 AND RSDOIEL 2026-05-04 18:30:00
Harvey routing to PI2 at ollama://192.168.1.2:11434. Workspace: /home/user/project.
RSDOIEL
@pi2 analyze this data
HARVEY
Forwarding to PI2.
PI2
Analysis: The data shows a normal distribution with mean 42.
Route: PI2 (registered via
/route add pi2 ollama://192.168.1.2:11434)
Character: PI2 (the route name as character)
Scene: EXT. — computation on the remote Pi machine
Scenario 3: Harvey Routing to Cloud Model via @mention
User uses @mention to direct a prompt to a cloud model registered as a route. The computation runs on the cloud provider’s infrastructure, so the scene is EXT.
EXT. MISTRAL AND RSDOIEL 2026-05-04 18:30:00
Harvey routing to MISTRAL (cloud API). Workspace: /home/user/project.
RSDOIEL
@mistral review this code
HARVEY
Forwarding to MISTRAL.
MISTRAL
The code follows good practices. Consider adding error handling for the edge case at line 42.
Character: MISTRAL (cloud model, registered as a route) Trigger: @mention in user dialogue Scene: EXT. — computation on remote cloud infrastructure
Scenario 4: Direct External Conversation (No Harvey)
Direct conversation with a remote model, bypassing Harvey entirely. EXT. is used because the computation is remote. HARVEY does not appear in the dialogue because Harvey is not involved.
EXT. CLAUDE AND RSDOIEL 2026-05-04 18:30:00
CLAUDE and RSDOIEL in direct conversation. Workspace: /home/user/project.
RSDOIEL
Explain quantum computing
CLAUDE
Quantum computing uses quantum bits (qubits) that can exist in superposition...
Note: HARVEY is absent from the dialogue because Harvey is not the routing intermediary. Contrast with Scenarios 2 and 3, where HARVEY appears as the forwarding character even though the scene is EXT.
Scenario 5: Unfulfilled @mention
User mentions a model that doesn’t respond.
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 18:30:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
(@julie mentioned but does not respond)
RSDOIEL
@julie what do you think?
HARVEY
Julie does not respond.
Note: The unfulfilled @mention is noted in the scene description.
Scenario 6: Multi-Model Within Scene
Multiple models introduced within a single scene via @mention.
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 18:30:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
RSDOIEL
@mistral review this, then @claude give a second opinion
HARVEY
Forwarding to MISTRAL.
MISTRAL
First opinion: The code is well-structured.
HARVEY
Forwarding to CLAUDE.
CLAUDE
Second opinion: I agree, but consider adding tests.
Note: This scenario only applies when the models are local (e.g. local aliases or Llamafile models). If @mistral and @claude are registered remote routes, each dispatch creates its own EXT. scene rather than appearing together in a single INT. scene.
Scene Types Reference
Chat Scenes
(INT. … AND … TALKING or EXT. … AND …)
Regular conversation between participants.
INT. example:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 18:30:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /path.
RSDOIEL
Prompt...
HARVEY
Response...
EXT. example (Harvey routing):
EXT. PI2 AND RSDOIEL 2026-05-04 18:30:00
Harvey routing to PI2 at ollama://192.168.1.2:11434. Workspace: /path.
RSDOIEL
Prompt...
HARVEY
Forwarding to PI2.
PI2
Response...
EXT. example (direct, no Harvey):
EXT. MISTRAL AND RSDOIEL 2026-05-04 18:30:00
MISTRAL and RSDOIEL in direct conversation. Workspace: /path.
RSDOIEL
Prompt...
MISTRAL
Response...
Context Recall Scene
(INT. CONTEXT RECALL)
Written once at session start, before the first chat scene, when
UnifiedMemory.Recall returns one or more results. One
[[recall:]] note per recalled memory item. Skipped entirely
when memory injection is off or no items were recalled.
INT. CONTEXT RECALL 2026-06-24 10:00:01
[[recall: workspace_profile_250928 (workspace_profile) — score 1.00]]
[[recall: tool_use_d55f70 (tool_use) — score 0.75]]
Agent Mode Scenes
(INT. AGENT MODE)
File write operations and other agent actions.
INT. AGENT MODE 2026-05-04 18:35:00
HARVEY
Harvey proposes to write 1 file(s) to the workspace.
HARVEY
Write path/to/file?
RSDOIEL
yes
[[write: path/to/file — ok]]
Fields: - Proposal:
Harvey proposes to write N file(s) to the workspace. -
Prompt: Write path? - Response: User’s
yes/no - Outcome:
[[write: path — status]]
Skill Scenes
(INT. SKILL <NAME>)
Skill activation and execution.
INT. SKILL FOUNTAIN-ANALYSIS 2026-05-04 18:40:00
Harvey executes the fountain-analysis skill.
FOUNTAIN-ANALYSIS
Reading agents/sessions/session.spmd for analysis.
Fields: - Skill name (from heading) - Description action line
Memory Scenes
(INT. MEMORY <TIMESTAMP>)
Memory documents stored in agents/memories/ use an
INT. MEMORY <TIMESTAMP> scene heading in place of the
standard session heading. This scene type is never recorded in
live sessions — it appears only in .spmd files
under agents/memories/{type}/ that were produced by
/memory mine.
The file begins with a YAML front matter block (replacing the Fountain title block) followed by a proper Fountain body.
File structure:
---
id: "git_fix_a3f891"
type: "tool_use"
created_at: "2026-05-25T12:00:00Z"
updated_at: "2026-05-25T12:00:00Z"
supersedes: []
tags: ["git", "error", "fix"]
description: "Fixed 'fatal: not a git repository' by running 'git init'"
summary: "When git reports 'fatal: not a git repository', running git init
in the project directory resolves the error by initializing a new repo."
source_session: "agents/sessions/harvey-session-20260525-103507.spmd"
---
FADE IN:
INT. MEMORY 2026-05-25 12:00:00
RSDOIEL
I got: fatal: not a git repository (or any of the parent directories).
HARVEY
Running git init to initialize the repository.
RSDOIEL
That fixed it.
THE END.
YAML front matter fields:
| Field | Required | Description |
|---|---|---|
id |
Yes | Unique identifier, format {type}_{6hex} |
type |
Yes | One of tool_use, workflow,
user_preference |
created_at |
Yes | RFC3339 timestamp |
updated_at |
Yes | RFC3339 timestamp |
supersedes |
Yes | IDs of memories this one replaces (empty list if none) |
tags |
Yes | Keyword list for filtering |
description |
Yes | One-sentence action-oriented summary |
summary |
Yes | 2-3 sentences optimised for semantic search |
source_session |
No | Path to the session this was mined from |
metadata |
No | Arbitrary key-value context |
Memory types:
| Type | Purpose |
|---|---|
tool_use |
A tool, command, or API trick that worked well |
workflow |
A multi-step process that should be repeated |
user_preference |
A stated or demonstrated user preference |
Directory layout:
agents/memories/
tool_use/ ← active tool_use memories
workflow/ ← active workflow memories
user_preference/ ← active user_preference memories
archive/ ← superseded memories (moved here, not deleted)
tool_use/
workflow/
user_preference/
memories.db ← SQLite index (FTS5 + vector embeddings)
manifest.yaml ← tracks which sessions have been mined
Workspace path normalisation: Absolute workspace
paths in memory content are replaced with the placeholder
<workspace> before the memory is saved, so memory
files do not embed machine-specific paths.
Parsing Rules for Tools
File Structure
^Title: .*$
^Credit: .*$
^Author: ([A-Z]+)$
^Date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
^Draft date: \d{4}-\d{2}-\d{2}$
^(Characters: .*)?$
^$
FADE IN:$
^$
Scene Parsing
- Match scene heading:
(INT|EXT)\. ([A-Z0-9_-]+) AND ([A-Z0-9_-]+) (TALKING)? (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) - Extract scene description: Lines between heading and first ALL-CAPS character
- Parse scene description:
Model: (.+)→ model identifierWorkspace: (.+)→ workspace path\(@(\w+) mentioned but does not respond\)→ unfulfilled @mention
- Parse dialogue:
- Character:
^[A-Z0-9_-]+$ - Dialogue: Subsequent lines until next character or blank line
- Character:
- Detect special syntax:
- Forwarding:
^Forwarding to ([A-Z0-9_-]+)\.$ - File write:
^\[\[write: (.+) — (ok|skipped|error:.+)\]\] - Tool note:
^\[\[(?:([A-Z0-9_-]+)\.)?tool: (.+) — (ok|error:.+)\]\] - RAG note:
^\[\[rag: (\d+) chunks from (.+), top score ([\d.]+)\]\] - Recall note:
^\[\[recall: (\S+) \((\S+)\) — score ([\d.]+)\]\] - @mention:
@([a-zA-Z][a-zA-Z0-9_-]*)
- Forwarding:
Character Type Detection
# Pseudocode
def character_type(name, scene_description, known_routes, author):
if name == "HARVEY":
return "harvey-native"
elif name in known_routes:
return "routed-ollama"
elif name == author:
return "human"
elif is_all_caps_alphanumeric(name):
return "cloud-model"
else:
return "unknown"Complete Example Sessions
Example 1: Basic Harvey Session (Local Model)
Title: Quick Question
Credit: Recorded by Harvey
Author: RSDOIEL
Date: 2026-05-04 10:00:00
Draft date: 2026-05-04
FADE IN:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 10:00:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project.
RSDOIEL
What is 2+2?
HARVEY
4
THE END.
Example 2: Multi-Model with @mention
Title: Code Review
Credit: Recorded by Harvey
Author: RSDOIEL
Date: 2026-05-04 14:00:00
Draft date: 2026-05-04
FADE IN:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 14:00:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/code.
RSDOIEL
@mistral review this function
HARVEY
Forwarding to MISTRAL.
MISTRAL
The function has a potential off-by-one error at line 23.
RSDOIEL
@claude can you confirm?
HARVEY
Forwarding to CLAUDE.
CLAUDE
Confirmed. The loop should use `<=` not `<`.
THE END.
Example 3: With File Operations
Title: Fix and Test
Credit: Recorded by Harvey
Author: RSDOIEL
Date: 2026-05-04 15:00:00
Draft date: 2026-05-04
FADE IN:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 15:00:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/code.
RSDOIEL
This function has a bug. Please fix it.
HARVEY
Here is the corrected version:
```go src/calc.go
func Add(a, b int) int {
return a + b
}
RSDOIEL /apply
INT. AGENT MODE 2026-05-04 15:02:00
HARVEY Harvey proposes to write 1 file(s) to the workspace.
HARVEY Write src/calc.go?
RSDOIEL yes
[[write: src/calc.go — ok]]
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 15:03:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/code.
RSDOIEL /run go test ./…
HARVEY All tests pass.
THE END.
### Example 4: Routed Ollama
Title: Cluster Query Credit: Recorded by Harvey Author: RSDOIEL Date: 2026-05-04 16:00:00 Draft date: 2026-05-04
FADE IN:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 16:00:00
Harvey and RSDOIEL are in chat mode. Model: ollama://192.168.1.2:11434. Workspace: /home/user/data.
RSDOIEL @pi2 process this dataset
HARVEY Forwarding to PI2.
PI2 Processing complete. 1000 records analyzed.
THE END.
### Example 5: Unfulfilled @mention
Title: Offline Model Credit: Recorded by Harvey Author: RSDOIEL Date: 2026-05-04 17:00:00 Draft date: 2026-05-04
FADE IN:
INT. HARVEY AND RSDOIEL TALKING 2026-05-04 17:00:00
Harvey and RSDOIEL are in chat mode. Model: llama3:latest. Workspace: /home/user/project. (@offline-model mentioned but does not respond)
RSDOIEL @offline-model what is your status?
HARVEY Offline-model does not respond.
THE END. ```
Validation Rules
Required Elements
| Element | Required | Validation |
|---|---|---|
Title: |
Yes | Non-empty |
Author: |
Yes | ALL-CAPS, non-empty |
FADE IN: |
Yes | Exact match |
THE END. |
Yes | Exact match at end |
| Scene headings | Per scene | Valid INT./EXT. format |
| Scene descriptions | Per scene | Contains Model: and Workspace: |
Character Validation
| Rule | Error |
|---|---|
| Character not ALL-CAPS | Warn: “Character name not uppercase: {name}” |
| Character in INT. scene not in heading | Warn: “Character {name} not in scene heading” |
| HARVEY missing from INT. scene | Warn: “INT. scene without HARVEY” |
| HARVEY in EXT. scene without routing action | Warn: “EXT. scene has HARVEY but no ‘Harvey routing to’ action line” |
| Unknown character type | Warn: “Unknown character type: {name}” |
Model Validation
| Rule | Error |
|---|---|
Missing Model: in description |
Warn: “Scene missing Model: declaration” |
| Model in description doesn’t match character | Warn: “Model mismatch: description={x}, character={y}” |
Best Practices
For Session Recording (Harvey)
- Always include
Model:or endpoint URL andWorkspace:in scene descriptions - Use INT. when computation runs locally (local Ollama, Llamafile, shell, file writes, skills)
- Use EXT. when computation runs remotely (registered routes, cloud APIs)
- Include HARVEY in EXT. dialogue when Harvey is the routing intermediary; omit HARVEY only for truly direct conversations
- Track @mentions: Note unfulfilled mentions in scene description
- Start new scenes for each discrete interaction (one scene per chat turn, route dispatch, shell command, etc.)
For Session Analysis
- Extract all characters from dialogue (not just heading)
- Track model timeline across scenes
- Distinguish Harvey-native vs forwarded responses
- Report @mention status (fulfilled/unfulfilled)
- Warn on inconsistencies (model mismatches, missing declarations)
For Human Readability
- Keep scene descriptions concise but informative
- Use parenthetical notes sparingly (for @mention tracking)
- Group related exchanges in single scenes when possible
- Start new scenes on major topic shifts or model changes
Compatibility Notes
Claude Code Compatibility
Harvey accepts .spmd files created by Claude Code. These
files may use slightly different formatting but follow the same
fundamental structure:
- Scene headings with character names
- Dialogue blocks under characters
- Scene descriptions between headings and dialogue
Differences to handle: - Claude Code may use different scene description formats - Model names may appear differently - File operations may use different syntax
Harvey’s parser is designed to be tolerant of these variations while maintaining strict output format for its own recordings.
Future Compatibility
The Fountain format is designed to be extensible. Future versions may add: - New scene types - Additional metadata fields - New special syntax elements
Older parsers should gracefully ignore unknown elements.
Changelog
| Version | Date | Changes |
|---|---|---|
| 1.2 | 2026-06-24 | Redefined INT./EXT. as local/remote computation; EXT. scenes now
used for route dispatch and cloud API calls; added
[[tool:]], [[CHARACTER.tool:]],
[[rag:]], [[recall:]] notes; added
INT. CONTEXT RECALL scene type |
| 1.1 | 2026-05-25 | Added INT. MEMORY <TIMESTAMP> scene type for
memory documents |
| 1.0 | 2026-05-04 | Initial specification with multi-model character attribution |
This document describes Harvey’s use of the Fountain format. For the official Fountain specification, see https://fountain.io.