OpenWriterControle/novel/docs/SCHEMA.md
cclohmar 3ce2d638a6
Some checks are pending
Create Release / Check if Version Bump PR Merged (push) Waiting to run
Create Release / Create Git Tag and GitHub Release (push) Blocked by required conditions
Post-Merge Version Bump / Check if Version Bump Needed (push) Waiting to run
Post-Merge Version Bump / Create Version Bump PR (push) Blocked by required conditions
feat(novel): add the OpenNovelWriter agent pack (10 agents, commands, schema, templates)
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.
2026-10-16 23:18:30 +01:00

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 OpenNovelAgent loads 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 → Kapitel
  • en → Chapter
  • pt → 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 .md file 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.md dictates 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 Illustrator is a subagent — OpenNovelAgent delegates 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, the meta: 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.