skip to main content

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 .spmd session 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

  1. 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})
  2. Extract scene description: Lines between heading and first ALL-CAPS character
  3. Parse scene description:
    • Model: (.+) → model identifier
    • Workspace: (.+) → workspace path
    • \(@(\w+) mentioned but does not respond\) → unfulfilled @mention
  4. Parse dialogue:
    • Character: ^[A-Z0-9_-]+$
    • Dialogue: Subsequent lines until next character or blank line
  5. 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_-]*)

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)

  1. Always include Model: or endpoint URL and Workspace: in scene descriptions
  2. Use INT. when computation runs locally (local Ollama, Llamafile, shell, file writes, skills)
  3. Use EXT. when computation runs remotely (registered routes, cloud APIs)
  4. Include HARVEY in EXT. dialogue when Harvey is the routing intermediary; omit HARVEY only for truly direct conversations
  5. Track @mentions: Note unfulfilled mentions in scene description
  6. Start new scenes for each discrete interaction (one scene per chat turn, route dispatch, shell command, etc.)

For Session Analysis

  1. Extract all characters from dialogue (not just heading)
  2. Track model timeline across scenes
  3. Distinguish Harvey-native vs forwarded responses
  4. Report @mention status (fulfilled/unfulfilled)
  5. Warn on inconsistencies (model mismatches, missing declarations)

For Human Readability

  1. Keep scene descriptions concise but informative
  2. Use parenthetical notes sparingly (for @mention tracking)
  3. Group related exchanges in single scenes when possible
  4. 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:

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.