OpenWriterControle/novel/docs/SCHEMA.md
cclohmar 4b9a535d6c
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
docs(novel): switch the pack to the container-vault layout
One Obsidian vault holds every book; each book is a subfolder and is the opencode
workspace. The pack is shared at the vault root and inherited by walking up, so a
book no longer gets its own .opencode copy:

- SCHEMA §1 rewritten: container vault -> book folders, shared .opencode + docs
- init.md: scaffolds only the book (AGENTS.md, DATA/, 01/), checks that a shared
  pack is reachable, and no longer copies agent/command files into the project
- PACK-NOTES: layout diagram + a headless section documenting the deny-based
  permission model
2026-10-16 23:36:04 +01:00

9.8 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: one container vault, one folder per book. A single Obsidian vault (e.g. "Novels") holds every book. Each book is a subfolder and is the workspace you open opencode in. The agent pack lives once, at the vault root, and is inherited by every book — a book never carries its own .opencode/. The canonical docs/SCHEMA.md likewise exists once, at the vault root.

Novels/                              # the container vault (Obsidian)
├── .opencode -> /Users/Shared/NovelPack/.opencode   # ONE shared agent pack
├── docs/ -> /Users/Shared/NovelPack/docs            # canonical SCHEMA.md
├── AGENTS.md                        # house rules that apply to every book
├── Scruffy/                         # a BOOK = a workspace
│   ├── AGENTS.md                    # this book's metadata and rules
│   ├── DATA/                        # this book's world
│   │   ├── 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
│   ├── 01/                          # Book 1 (folder = number, title optional)
│   │   ├── DE/                      # language folder (ISO-639-1 code)
│   │   │   ├── Kapitel 001.md
│   │   │   └── ...
│   │   ├── EN/
│   │   │   ├── Chapter 001.md
│   │   │   └── ...
│   │   └── images/                  # illustrations for this book
│   │       ├── prompts/             # image prompts (Markdown, one per image)
│   │       └── generated/           # generated image files
│   └── 02/                          # Book 2 of the same series
└── Kessler/                         # another book — same shape, own AGENTS.md + DATA/

Multiple books in parallel

Each book is a separate folder inside the one vault. opencode is always started inside the book folder; it finds the shared pack by walking up to the vault root, so books never duplicate the agents. The OpenNovelAgent is identical everywhere — what makes a workspace "the Scruffy book" vs. "the Kessler book" is its own AGENTS.md + DATA/. Switch books by switching folders; never put two books in one folder. (If several books live in one vault and a book needs to be verifiable on its own, make the book folder a git repository — not the vault.)

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.