The novel-writing agent pack existed only as three byte-identical copies inside
Obsidian vaults (Die-Kessler-Zwillinge, Scruffy-der-Weltenhund, OpenNovelWriter),
with no version control anywhere. It is now versioned here as the single source
of truth.
Contents (novel/):
- .opencode/agent/ OpenNovelAgent (primary) + LineEditor, Proofreader,
StyleAnalyst, ContinuityEditor, StoryReviewer, Translator, Importer,
Illustrator, CopyrightWatchdog
- .opencode/command/ import.md, init.md
- .opencode/languages.yaml, .opencode/opencode.json (pristine: default_agent)
- docs/SCHEMA.md canonical schema — the newer OpenNovelWriter revision, which
supersedes the stale copy in the Scruffy vault (adds workspace = book,
images/prompts + images/generated, parallel books, rewrites section 7)
- templates/ AGENTS.md placeholder + DATA/{wiki,timeline,glossary}.yaml.md, style.md
- sync-to-vault.sh dry-run by default; --apply backs up what it replaces and
never touches DATA/, AGENTS.md, chapters or a vault's own opencode.json
- PACK-NOTES.md per-file md5 provenance and the verified cross-vault comparison
Verified before committing: all 10 agents, both commands, languages.yaml and
start.sh are md5-identical across the three vaults.
9.3 KiB
OpenNovelWriter — SCHEMA
Canonical reference for the OpenNovelWriter ecosystem. These conventions apply to ALL authors and projects — not just a single book. The
OpenNovelAgentloads this document to handle structure, filenames, and data formats correctly.
1. Project Structure
Concept: workspace = book. One book (or series) = one folder = one workspace
= one Obsidian vault. The author creates and names the vault first (e.g.
"Die Kessler Zwillinge"), then runs /init inside it. The vault's own name is
the project name; /init scaffolds into it directly (no nested subfolder).
The project directory is organized like a Git repository:
[Series Title]/ # the workspace/vault (named by the author)
├── .opencode/ # agent configuration (local, via /init)
│ ├── agent/
│ ├── command/
│ └── opencode.json
├── 01/ # Book 1 (folder = number, title optional)
│ ├── DE/ # language folder (ISO-639-1 code)
│ │ ├── Kapitel 001.md
│ │ ├── Kapitel 002.md
│ │ └── ...
│ ├── EN/
│ │ ├── Chapter 001.md
│ │ └── ...
│ └── images/ # illustrations for this book
│ ├── prompts/ # image prompts (Markdown, one per image)
│ └── generated/ # generated image files
├── 02/ # Book 2
├── DATA/
│ ├── wiki.yaml.md # world wiki (canonical)
│ ├── timeline.yaml.md # timeline (lore history + plot)
│ ├── glossary.yaml.md # translation glossary
│ └── style.md # the author's writing style
├── AGENTS.md # project rules (read by the agent)
└── README.md # human overview
Multiple books in parallel
Each book is a separate workspace (separate folder, separate opencode
workspace). The OpenNovelAgent is the same everywhere — what makes a workspace
"the Scruffy book" vs. "the Kessler book" is its own AGENTS.md + DATA/.
Switch workspaces to switch books; do not try to fit multiple books in one folder.
2. Naming Conventions
| Element | Rule | Example |
|---|---|---|
| Book folder | number (2-digit), title optional | 01 → later 01 - Der Dieb im Eulental |
| Language folder | ISO-639-1 code (code only) | DE, EN, PT |
| Chapter file | localized chapter word + 3-digit number | Kapitel 001.md |
| Chapter number | 3 digits, zero-padded | 001 … 100 |
| DATA files | fixed English names | wiki.yaml.md, timeline.yaml.md, glossary.yaml.md |
Chapter word per language (defined in .opencode/languages.yaml):
de→Kapitelen→Chapterpt→Capítulo- (the community can add more languages)
Important: language folder names are ALWAYS the code (DE), never spelled out. Chapter files use the localized word.
3. Data Format: YAML inside .md code blocks
All DATA files are .yaml.md files: Markdown files whose content is a ```yaml code block.
# Title (optional, human-readable)
```yaml
meta:
title: "..."
**Why:** Obsidian renders the code block cleanly; the AI assistant strips the ` ```yaml ` markers and reads the content as pure YAML.
---
## 4. Key Language: English, Values: localized
**Canonical rule:** YAML **keys** are always English and stable. YAML **values** are in the author's canonical language.
```yaml
# CORRECT — keys English, values German
characters:
- name: "Leah Kessler"
role: "Hauptcharakter"
# WRONG — localized keys (breaks the schema)
characters:
- name: "Leah Kessler"
Rolle: "Hauptcharakter"
Reason: the agent parses keys reliably regardless of the canonical language. An author in Spain uses the same schema; only the values are Spanish.
5. DATA File Schemas
5.1 wiki.yaml.md — World Wiki
meta:
title: "" # series title
author: "" # author
canonical: "" # ISO-639-1 (writing language)
languages: [] # publication languages
genre: ""
audience: ""
concept: {} # premises, series ideas (keys are free-form)
characters: [] # people
locations: {} # places
magic: {} # magic system, spells, creatures
5.2 timeline.yaml.md — Timeline
history: # lore history (world background, beyond the plot)
- date: "" # ISO date OR free text (e.g. "1268-12", "long ago")
event: ""
story: # plot events (the fictional present)
- date: "" # e.g. "2011-08"
book: 1 # optional, when multiple books
chapter: 13 # optional
event: ""
Rule: history = world background (e.g. a dragon hatches in 1268). story = plot progression (e.g. the 2011 school year). Both live in ONE file.
5.3 glossary.yaml.md — Translation Glossary
terms:
- de: "" # canonical term
en: "" # translation (or missing)
# pt: "" # more languages as additional keys
Rule: a term is defined ONCE and used consistently throughout the story. The ContinuityEditor checks translations against this glossary.
6. Chapter Conventions
- One
.mdfile per chapter. - First line:
# [Chapter word] NNN - Title(localized chapter word). - Prose follows
style.md(the author's voice). - Numbers written out in prose, if
style.mddictates it.
7. Images & Illustrations
Each book has an images/ folder for illustrations. The Illustrator subagent
handles image generation.
01/images/
├── prompts/ # one .md per image — the prompt + metadata
└── generated/ # the actual image files (png/jpg/webp)
Prompt file convention (images/prompts/NNN - description.md):
---
chapter: 006 # optional — which chapter the image illustrates
character: "Scruffy" # optional — subject(s)
status: draft # draft | approved | generated
---
The image prompt (written in the author's language) that was sent to the
image generator, plus a short note on why this image matters to the story.
Rules:
- Prompts are derived from the wiki (character appearance, locations) so images stay consistent with the story.
- The
Illustratoris a subagent —OpenNovelAgentdelegates image requests to it, it does not interrupt the author. - Generated files land in
images/generated/, named to match their prompt file.
8. The Co-Authoring Cycle
Author: "next chapter: X should happen"
↓
Agent loads: AGENTS.md + DATA/ (wiki, timeline, glossary, style) + previous chapter summary
↓
Agent proposes a chapter draft (beats, POV, ~length) → author approves
↓
Agent writes the chapter → author reads/edits in Obsidian
↓
Agent harvests new facts (characters, events) → updates wiki.yaml.md / timeline.yaml.md
8. Context-Window Strategy (long works)
- Always loaded:
AGENTS.md,style.md, themeta:block, current chapter outline + previous chapter summary. - On-demand (RAG): remaining wiki entries, specific spells/places — load only when the chapter touches them.
- Never read the whole manuscript at once — reference it via
timeline.yaml.md(summaries).
9. Temperature Policy (creativity vs. hallucination)
Temperature is set per agent role, not once for the whole system. The principle: creative agents run hot (imagination), verification agents run cold (accuracy).
| Agent | Role | Temp | Rationale |
|---|---|---|---|
OpenNovelAgent |
Creative drafting | 0.8 | Imagination — the "write prose" brain |
Illustrator |
Image prompt/creation | 0.7 | Creative visual, but grounded in wiki |
PlotArchitect |
Plot structure | 0.6 | Creative but coherent |
CharacterDeveloper |
Character depth | 0.6 | Creative |
Translator |
Translation | 0.4 | Fidelity first, some idiom |
StyleAnalyst |
Voice extraction | 0.2 | Pattern-finding, not inventing |
Importer |
Migration/extraction | 0.2 | Faithful reconstruction, not invention |
StoryReviewer |
Editorial quality review | 0.3 | Constructive critique, report-only |
LineEditor |
Word choice / naturalness | 0.3 | Catch semantic errors grammar misses |
ContinuityEditor |
Fact/consistency check | 0.1 | Hallucination freedom — like a code reviewer |
Proofreader |
Grammar/spelling | 0.1 | Mechanical precision, no restyling |
CopyrightWatchdog |
Copyright-risk check | 0.1 | Flag expression, not ideas; report-only |
StoryRetriever |
Retrieval/search | 0.1 | Accurate lookup, no creativity |
Why this works: the hot agent invents the prose; the cold agent verifies it (catches contradictions — changed eye color, timeline breaks). This is the same "generator hot / reviewer cold" split as code agents, applied to fiction.
Each agent's temperature lives in its own frontmatter and can be tuned per author.
10. Versioning
The project directory is a Git repository. Every chapter approval = a commit. This enables rollback and community collaboration.