🌍 ChapterWise Codex Format V1.2

The ChapterWise Codex Format is a perfectly recursive specification designed for complex storytelling projects, universe-scale world-building, and cross-media narratives. Every part of a codex can become its own standalone file, creating a beautiful fractal structure where the same format works at every level.

Version: 1.2 β€” Enhanced tag array support with weighted display
Status: Stable
Date: November 30, 2025


Table of Contents

  1. Introduction
  2. Design Philosophy
  3. File Formats
  4. Basic Structure
  5. Metadata Object
  6. Entity Fields
  7. Content Structures
  8. Attributes Array
  9. Relations Array
  10. Children Array
  11. Include Directives
  12. Media Handling
  13. Tagging System
  14. Complete Examples
  15. Best Practices
  16. Working with Git Projects
  17. Migration from Legacy Formats
  18. Validation
  19. JSON Format Examples
  20. Technical Specification

Introduction

Purpose

The ChapterWise Codex Format provides a unified structure for representing complex storytelling content, from individual characters to entire fictional universes. The key innovation of V1.0 is perfect recursion β€” any slice of a codex can become its own standalone file.

Key Features

  • Perfect Recursion: Identical structure at all hierarchy levels
  • No Data Wrapper: Content lives directly at root level
  • Metadata Consolidation: All format information in one object
  • Include Support: Compose files from multiple sources
  • Maximum Flexibility: Only one required field (metadata.formatVersion)
  • Media-Aware: Built-in support for images and rich media

Design Philosophy

Perfect Recursion

The defining feature of V1.0 is perfect recursion: any slice of a codex can become a standalone codex file. There's no special "wrapper" or "envelope" β€” just entities all the way down. A character's skill can use the same format as the entire universe.

Core Principles

  • Identical structure everywhere β€” Root, child, grandchild all use the same keys
  • No data wrapper β€” Content lives directly at root level
  • Metadata consolidation β€” All format info in one metadata object
  • Include directives β€” Embed external files at any level
  • Maximum flexibility β€” Only metadata.formatVersion is required
  • Media-aware β€” Built-in support for images, galleries, and rich media

Fractal Beauty

Universe (codex)
  β”œβ”€β”€ Epoch (codex)
  β”‚     β”œβ”€β”€ Book (codex)
  β”‚     β”‚     β”œβ”€β”€ Chapter (codex)
  β”‚     β”‚     └── Character (codex)
  β”‚     β”‚           β”œβ”€β”€ Arc (codex)
  β”‚     β”‚           └── Skill (codex)

Each node is a full codex β€” you can extract any piece and it's a valid standalone file.

Design Goals

  1. Simplicity: Minimize required fields, maximize flexibility
  2. Composability: Enable file inclusion and modular design
  3. Extensibility: Support arbitrary attributes and relations
  4. Human-Friendly: Optimize for YAML readability
  5. Machine-Parseable: Clean JSON representation

File Formats

.codex.yaml or .codex files are the preferred format:

  • βœ… Human-readable and editable
  • βœ… Native multiline text blocks (| and >)
  • βœ… Comments for documentation (#)
  • βœ… Natural list and object syntax
  • βœ… Better version control diffs
  • βœ… Markdown-friendly content

JSON Format

.codex.json files are supported for:

  • API integration and programmatic access
  • Legacy system compatibility
  • Machine processing pipelines
  • High-performance parsing

YAML and JSON are semantically equivalent. Parsers support both formats and allow conversion between them.

File Extensions

  • YAML: .codex.yaml, .codex, .yaml
  • JSON: .codex.json, .json

Character Encoding

  • UTF-8 encoding required
  • BOM (Byte Order Mark) optional
  • Line endings: LF (\n) recommended, CRLF (\r\n) acceptable

Basic Structure

Minimal Codex

The absolute minimum codex file:

metadata:
  formatVersion: "1.0"

That's it! Everything else is optional.

Simple Character

metadata:
  formatVersion: "1.0"
  documentVersion: "1.0.0"
  created: "2025-10-25T12:00:00Z"
  author: "Author Name"

id: "char-livia-uuid"
type: character
name: "Livia Mercuria"
summary: "Roman noblewoman turned rebel leader"

Character with Background

metadata:
  formatVersion: "1.0"
  documentVersion: "1.2.0"
  author: "Author Name"
  license: "CC BY-SA 4.0"

id: "char-livia-uuid"
type: character
name: "Livia Mercuria"
summary: "Roman noblewoman turned rebel leader"

body: |
  Born into privilege in 75 BCE, Livia discovered her past-life 
  memories at age sixteen. Her awakening sparked a transformation 
  that would shake the foundations of the Roman Republic.

attributes:
  - key: house
    name: "Noble House"
    value: "Mercuria"

  - key: strength
    name: "Strength"
    value: 18
    dataType: int

tags:
  - protagonist
  - roman-era
  - awakened

No Data Wrapper

Unlike legacy formats, V1.0 has no data wrapper. Content lives directly at the root level:

# ❌ Legacy format (NOT V1.0)
data:
  id: "uuid"
  name: "Character"

# βœ… V1.0 format
id: "uuid"
name: "Character"

Metadata Object

The metadata object consolidates all format and document information. It MUST appear at the root level of every codex file.

Required Field

  • formatVersion β€” string (REQUIRED)
    Must be "1.2" for this specification (V1.0 and V1.1 are also supported for backwards compatibility)
metadata:
  formatVersion: "1.2"  # βœ… Correct (latest)
  formatVersion: "1.1"  # βœ… Also valid (backwards compatible)
  formatVersion: "1.0"  # βœ… Also valid (backwards compatible)
  formatVersion: 1.2    # ❌ Wrong (must be string)
  formatVersion: "1"    # ❌ Wrong (must be "1.0", "1.1", or "1.2")

Optional Fields

  • documentVersion β€” string
    Semantic version of this document (e.g., "1.2.3")

  • created β€” string
    ISO-8601 timestamp of creation (e.g., "2025-10-25T15:30:00Z")

  • updated β€” string
    ISO-8601 timestamp of last update

  • author β€” string or array
    Author name(s) β€” can be a single string or array of strings

  • license β€” string
    License identifier (e.g., "CC BY-SA 4.0", "All Rights Reserved")

  • tags β€” array
    Document-level tags for organization

  • iconset β€” string
    Icon library to use: "phosphor", "fontawesome", or "lucide"

Example Metadata

Minimal:

metadata:
  formatVersion: "1.2"

Full:

metadata:
  formatVersion: "1.2"
  documentVersion: "2.1.0"
  created: "2025-01-15T00:00:00Z"
  updated: "2025-11-30T00:00:00Z"
  author: "Anson Phong"
  license: "CC BY-SA 4.0"
  tags:
    - 11-lives
    - epoch-02
    - canon
  iconset: "phosphor"

Multiple Authors:

metadata:
  formatVersion: "1.2"
  author:
    - "Author One"
    - "Author Two"
    - "Editor Name"

Entity Fields

All these fields are optional and can appear at any level (root, child, grandchild):

Identity

  • id β€” string β€” Unique identifier (UUID v4 recommended)
  • type β€” string β€” Entity classification (e.g., "character", "location", "chapter")
  • name β€” string β€” Primary name/identifier
  • title β€” string β€” Display title (optional alternative to name)
  • key β€” string β€” Human-readable slug for cross-references

Content

  • summary β€” string β€” Brief description or tagline
  • body β€” string β€” Main content body (supports markdown)
  • content β€” array β€” Structured content objects (see below)

Organization

  • tags β€” array β€” Entity-level tags for cross-referencing
  • attributes β€” array β€” Key-value metadata pairs
  • relations β€” array β€” Links to other entities
  • children β€” array β€” Nested child entities (RECURSIVE!)

Media

  • image β€” string β€” Primary image URL
  • images β€” array β€” Image gallery
  • external_url β€” string β€” External reference URL
  • animation_url β€” string β€” Animation/video URL

Presentation

  • display β€” object β€” Visual presentation settings (see Display Settings)

Display Settings

The display field controls visual presentation at any hierarchy level. Settings automatically cascade to all descendants, and children can override parent settings.

Fields

  • breadcrumb β€” boolean β€” Show parent breadcrumb in title (default: true)
  • icon β€” boolean β€” Show type icon (default: true)
  • type β€” boolean β€” Show type badge (default: true)

Inheritance

Display settings cascade automatically to all descendants (children, grandchildren, etc.). Child settings override parent settings for that specific property.

Examples

Hide breadcrumb for a list and all its children:

id: shot-list
type: shot-list
name: Shot List
display:
  breadcrumb: false

children:
  - id: core-anchors
    type: shot-category
    name: Core Anchors
    # Inherits: breadcrumb=false, icon=true, type=true

  - id: work-beats
    type: shot-category
    name: Work Beats
    # Inherits: breadcrumb=false, icon=true, type=true

Override specific settings in a child:

id: parent-section
type: section
name: Parent Section
display:
  breadcrumb: false
  icon: true
  type: false

children:
  - id: child-section
    type: section
    name: Child Section
    # Inherits: breadcrumb=false, type=false
    # But overrides icon
    display:
      icon: false
    # Final: breadcrumb=false, icon=false, type=false

Clean list presentation:

id: checklist
type: checklist
name: Pre-Flight Checklist
display:
  icon: false
  type: false
  breadcrumb: false

children:
  - id: item-1
    type: checklist-item
    name: Check fuel levels
    # All display elements hidden by inheritance

Content Structures

The Body Field

The body field is a markdown-formatted text block that can appear at any hierarchy level. It's rendered prominently and supports full markdown formatting.

Usage

id: "char-aya-uuid"
type: character
name: "Aya"
summary: "Atlantean priestess with prophetic sight"

body: |
  # Background

  Born under the constellation of the Eternal Flame, Aya was marked 
  from birth with the silver crescent upon her browβ€”a sign recognized 
  by the Druids as divine blessing.

  ## The Awakening

  At sixteen, during the ritual of Temporal Resonance, Aya alone 
  remained conscious as the Great Pyramid's crystal matrix overloaded. 
  The experience granted her **temporal sight**β€”the ability to perceive 
  probability streams.

  ### Key Relationships
  - **Thoth**: Her mentor who concealed her true parentage
  - **Marcus**: Her companion across lifetimes
  - **The Council**: Those who fear her power

Rendering

The body field is rendered: * Below summary and attributes * Above content sections and children * With full markdown support (headers, lists, bold, italic, links, code, blockquotes) * Using consistent typography across all levels

The Content Array

For structured content (like screenplay beats or game moves), use the content array:

id: "beat-pyramid-meltdown-uuid"
type: beat
name: "The Pyramid Meltdown"

content:
  - key: visual
    name: "Visual"
    value: |
      The crystal matrix begins to glow with unstable light. 
      Aya stands at the center, her silver crescent blazing.

  - key: narration
    name: "Narration"
    value: |
      As the others fall unconscious, Aya alone sees the threads 
      of time itselfβ€”past and future converging in this moment.

  - key: audio
    name: "Audio"
    value: "Resonant crystal tones building to crescendo"

  - key: duration
    name: "Duration"
    value: "02:30"

Each content item can have: * key β€” Machine-readable identifier (required) * name β€” Display label (optional) * value β€” Content (string, supports multiline with |) (required) * id β€” Optional unique ID * type β€” Optional type classifier


Attributes Array

Attributes store key-value metadata. They're flexible and extensible:

attributes:
  - key: house
    name: "Noble House"
    value: "Mercuria"

  - key: strength
    name: "Strength"
    value: 18
    dataType: int

  - key: special_abilities
    name: "Special Abilities"
    value:
      - temporal-sight
      - empathic-healing
      - dream-walking
    dataType: array

  - key: soul_archetype
    name: "Soul Archetype"
    value: "Aya-Prime"
    tags:
      - core-identity
      - reincarnation

Attribute Fields

  • key β€” string (required) β€” Machine-readable identifier
  • name β€” string β€” Human-readable label
  • value β€” any (required) β€” The actual value (string, number, boolean, array, object)
  • dataType β€” string β€” Type hint: "int", "float", "boolean", "array", "date", "url", "markdown", etc.
  • tags β€” array β€” Classification tags for this attribute

Data Types

Common dataType values:

  • int β€” Integer number
  • float β€” Decimal number
  • boolean β€” True/false value
  • string β€” Text string
  • array β€” List of values
  • object β€” Complex object
  • date β€” ISO-8601 date/timestamp
  • url β€” Web URL
  • markdown β€” Markdown-formatted text

Relations Array

Relations create graph connections between entities:

relations:
  - targetId: "char-aya-epoch01-uuid"
    kind: "reincarnation-of"
    strength: 0.95
    attributes:
      - key: soul_continuity
        name: "Soul Continuity"
        value: 0.95
      - key: memory_retention
        name: "Memory Retention"
        value: 0.2

  - targetId: "char-marcus-uuid"
    kind: "loves"
    strength: 1.0
    reciprocal: true

Relation Fields

  • targetId β€” string (required) β€” UUID of target entity
  • targetKey β€” string β€” Human-readable key of target
  • kind β€” string (required) β€” Relationship type
  • strength β€” number β€” Intensity (0.0 to 1.0)
  • reciprocal β€” boolean β€” Whether to create reverse relation
  • attributes β€” array β€” Metadata about this specific relationship

Common Relation Kinds

Hierarchical: * parent / child * contains / contained-by * part-of / has-part

Narrative: * ally / enemy * loves / loved-by * mentors / student-of * reincarnation-of / reincarnates-as

Temporal: * precedes / follows * causes / caused-by * concurrent-with

Cross-Media: * appears-in * referenced-in * variant-of

Reverse Relations

When reciprocal: true, the system creates the inverse relation automatically:

# Entity A
relations:
  - targetId: "entity-b-uuid"
    kind: "loves"
    reciprocal: true

# System automatically creates in Entity B:
# relations:
#   - targetId: "entity-a-uuid"
#     kind: "loved-by"

Children Array

Children create the recursive hierarchy β€” the heart of V1.0:

id: "universe-atlantis-uuid"
type: universe
name: "Atlantis Chronicles"

children:
  - id: "epoch-01-uuid"
    type: epoch
    name: "Epoch 01: Atlantis"
    summary: "The golden age before the flood"

    children:
      - id: "char-aya-uuid"
        type: character
        name: "Aya"
        summary: "Atlantean priestess"

        children:
          - id: "arc-awakening-uuid"
            type: arc
            name: "The Awakening"

            children:
              - id: "beat-pyramid-uuid"
                type: beat
                name: "Pyramid Meltdown"

Each child uses the exact same structure β€” that's the beauty of perfect recursion!

Standalone Children

Any child can have its own metadata and become a standalone codex:

children:
  - metadata:
      formatVersion: "1.0"
      documentVersion: "1.0.0"
      author: "Different Author"
    id: "skill-uuid"
    type: skill
    name: "Blade Dance"

Order Preservation

The order of children is significant and preserved:

children:
  - type: preface
    name: "Preface"      # Position 0
  - type: chapter
    name: "Chapter 1"    # Position 1
  - type: chapter
    name: "Chapter 2"    # Position 2
  - type: epilogue
    name: "Epilogue"     # Position 3

Include Directives

The include field lets you embed external codex files with full or selective content inclusion.

Simple Include (Full Content)

Include the entire file using string syntax (backwards compatible):

id: "party-main-uuid"
type: group
name: "The Adventuring Party"

children:
  - include: "/Characters/Aya.codex.yaml"
  - include: "/Characters/Marcus.codex.yaml"
  - include: "/Characters/Thoth.codex.yaml"

Referenced file (/Characters/Aya.codex.yaml):

metadata:
  formatVersion: "1.1"

id: "char-aya-uuid"
type: character
name: "Aya"
summary: "Atlantean priestess with prophetic sight"
body: |
  Born under the constellation of the Eternal Flame...

When parsed, the included file is embedded in place as if it were written inline.

Selective Include (Specific Fields)

New in V1.1: Include only specific fields from a file using object syntax:

children:
  - include:
      file: "/Characters/Aya.codex.yaml"
      fields: ["summary", "image", "attributes"]

This includes only the summary, image, and attributes fields from Aya's file, ignoring everything else.

Path Resolution Rules

Absolute Project Paths (start with /): * Resolved relative to Git project root * Example: /E02/characters/Aya.codex.yaml

Relative Paths (no slash or starts with ./): * Resolved relative to current file's directory * characters/Aya.codex.yaml is same as ./characters/Aya.codex.yaml * Parent directory: ../characters/Aya.codex.yaml

Examples:

If parent file is /E02/scenes/Scene-01.codex.yaml: * beats/Beat-01.codex.yaml β†’ /E02/scenes/beats/Beat-01.codex.yaml * ./beats/Beat-01.codex.yaml β†’ /E02/scenes/beats/Beat-01.codex.yaml * ../characters/Aya.codex.yaml β†’ /E02/characters/Aya.codex.yaml * /E02/locations/Rome.codex.yaml β†’ /E02/locations/Rome.codex.yaml

Field Specifications

Simple Fields:

fields: ["summary", "body", "image", "tags"]

Nested Attributes (filter by key):

fields: ["attributes.duration", "attributes.location"]
# Returns only attributes where key="duration" or key="location"

Array Fields (entire array):

fields: ["images", "relations", "content"]
# Includes all items in the array

All Children:

fields: ["children"]
# Includes all children from the file

Specific Child by ID:

fields: ["children.id:char-uuid-123"]
# Includes only the child with id="char-uuid-123"

Complete Examples

Mixed Syntax in Same Array:

children:
  # Full include (string syntax)
  - include: "/Characters/Aya.codex.yaml"

  # Summary only (selective)
  - include:
      file: "/Characters/Marcus.codex.yaml"
      fields: ["summary"]

  # Specific attributes from beats
  - include:
      file: "beats/Beat-01.codex.yaml"
      fields: ["name", "summary", "attributes.duration", "content"]

Relative Path Example:

# In file: /E02/scenes/Scene-01.codex.yaml

children:
  # Relative to current directory
  - include:
      file: "beats/Beat-01.codex.yaml"
      fields: ["summary", "content"]

  # Parent directory
  - include:
      file: "../characters/Aya.codex.yaml"
      fields: ["summary", "image"]

  # Absolute project path
  - include:
      file: "/E02/locations/Rome.codex.yaml"
      fields: ["summary"]

Screenplay Beat References:

# In: /Project/Acts/Act-01.codex.yaml
children:
  - include:
      file: "../Beats/Opening.codex.yaml"
      fields: ["summary", "attributes.duration", "content"]

  - include:
      file: "../Beats/Inciting.codex.yaml"
      fields: ["summary", "attributes.duration", "content"]

Include Rules

  1. Path Format: Absolute (/path) or relative (path or ./path)
  2. File Extension: Typically .codex.yaml or .codex.json
  3. Valid Codex: Included file must be valid V1.0+ codex
  4. Recursive: Included files can contain their own includes
  5. Circular Detection: Circular includes are detected and prevented
  6. Security: Paths cannot escape project directory

Resolution Process

When parser encounters an include:

  1. Detect Syntax: String (full) or object (selective)
  2. Resolve Path: Apply path resolution rules
  3. Load: Read the referenced file
  4. Parse: Parse as V1.0+ codex
  5. Filter (selective only): Extract specified fields
  6. Embed: Replace include directive with content
  7. Recurse: Process any includes in embedded content

Media Handling

Simple Image

image: "/images/characters/livia-portrait.jpg"
images:
  - url: "/images/livia/portrait-01.jpg"
    caption: "Official portrait in senatorial robes"

  - url: "/images/livia/sketch-02.jpg"
    caption: "Early concept sketch"

  - url: "https://example.com/reference.jpg"
    caption: "Historical reference"

Image Item Structure: * url β€” string (required) β€” Image URL * caption β€” string β€” Display caption * alt β€” string β€” Alt text for accessibility * featured β€” boolean β€” Mark as featured

Media Array (Advanced)

media:
  - source_type: "url"
    source: "/images/livia/portrait.jpg"
    media_type: "image"
    featured: true
    caption: "Character portrait"

  - source_type: "url"
    source: "/video/livia-intro.mp4"
    media_type: "video"
    caption: "Character introduction"

Path Resolution

Image paths in Git-based projects:

Relative Paths (start with /): * /images/file.jpg β†’ Resolved relative to Git project root * App converts to: /projects/{project-id}/files/images/file.jpg

Absolute URLs: * https://example.com/image.jpg β†’ Used as-is * ipfs://bafy.../image.jpg β†’ Used as-is


Tagging System

Tags can be stored in two formats: simple (array of strings) or detailed (array of objects with counts). Both formats are valid and can be used at any level. New in V1.2: The renderer now fully supports both formats with weighted display for counted tags.

Simple Format (Strings)

The most common format β€” an array of tag strings:

tags:
  - 11-lives          # Series identifier
  - epoch-02          # Time period
  - protagonist       # Narrative function
  - reincarnation     # Special property
  - roman-era         # Historical context

Detailed Format (Objects with Counts)

For auto-generated tags or when frequency matters, use objects with name and count:

tags:
  - name: Roman
    count: 15
  - name: Awakening
    count: 8
  - name: Senate Chamber
    count: 5
  - name: Memory
    count: 4

Detailed Tag Fields: * name β€” string (required) β€” The tag text * count β€” number (optional) β€” Frequency/weight of this tag

Mixed Format

You can mix both formats in the same array (though not recommended for consistency):

tags:
  - protagonist                    # Simple string
  - name: Roman                    # Detailed object
    count: 15
  - roman-era                      # Simple string

Entity-Level Tags

Tags at the entity level for cross-referencing and filtering:

id: char-livia-uuid
type: character
name: "Livia Mercuria"
tags:
  - protagonist
  - awakened
  - roman-era

Attribute-Level Tags

Tags can also be applied to individual attributes:

attributes:
  - key: strength
    name: "Strength"
    value: 18
    dataType: int
    tags:
      - stat
      - physical
      - core-attribute

Document-Level Tags (in Metadata)

Tags in the metadata section apply to the entire document:

metadata:
  formatVersion: "1.1"
  tags:
    - draft
    - needs-review
    - canon

Auto-Generated Tags

The ChapterWise Codex VS Code extension can automatically generate tags from body content using the Generate Tags command. This uses NLP-based extraction with:

  • Unigram and bigram (phrase) detection
  • Stopword filtering
  • Heading text boosting
  • Minimum frequency thresholds

Generated tags can be output in either simple or detailed format.

Weighted Tag Display (V1.2)

When tags include count values, the ChapterWise renderer displays them with weighted sizing β€” tags with higher counts appear larger, creating a visual tag cloud effect:

  • Simple tags (strings): Displayed uniformly with standard size
  • Weighted tags (objects with count): Displayed with variable sizes based on relative frequency
  • Mixed arrays: Both formats render correctly in the same tag section

The size calculation uses the minimum and maximum counts in the array to normalize tag sizes, ensuring visual consistency across different count ranges.


Complete Examples

Complete Character Example

Here's a full V1.2 codex showing all features:

metadata:
  formatVersion: "1.2"
  documentVersion: "2.1.0"
  created: "2025-01-15T00:00:00Z"
  updated: "2025-11-30T15:30:00Z"
  author: "Anson Phong"
  license: "CC BY-SA 4.0"
  tags:
    - 11-lives
    - epoch-02
    - canon

id: "char-livia-11l02-uuid"
type: character
name: "Livia Mercuria"
title: "Livia Mercuria, The Rebel Senator"
summary: "Roman noblewoman who became a rebel leader after awakening to past-life memories"

body: |
  # Background

  Born in 75 BCE into the wealthy Mercuria merchant family, Livia was 
  expected to marry well and live quietly. Instead, she discovered her 
  past-life memories at sixteen and became a force that would challenge 
  the Roman Republic itself.

  ## The Awakening

  During a Senate ceremony, Livia experienced a sudden flood of memories 
  from her previous life as Aya, the Atlantean priestess. This awakening 
  changed everything.

image: "/images/livia/portrait-senatorial.jpg"

images:
  - url: "/images/livia/portrait-01.jpg"
    caption: "In senatorial robes"
  - url: "/images/livia/sketch-youth.jpg"
    caption: "As a young woman"

tags:
  - protagonist
  - awakened
  - roman-era
  - epoch-02

attributes:
  - key: house
    name: "Noble House"
    value: "Mercuria"

  - key: soul_archetype
    name: "Soul Archetype"
    value: "Aya-Prime"

  - key: epoch_code
    name: "Epoch Code"
    value: "11L02"

  - key: incarnation_number
    name: "Incarnation Number"
    value: 2
    dataType: int

  - key: strength
    name: "Strength"
    value: 18
    dataType: int

  - key: special_abilities
    name: "Special Abilities"
    value:
      - temporal-sight
      - empathic-healing
      - political-cunning

relations:
  - targetId: "char-aya-11l01-uuid"
    kind: "reincarnation-of"
    strength: 0.95
    attributes:
      - key: soul_continuity
        value: 0.95
      - key: memory_retention
        value: 0.2

  - targetId: "char-marcus-11l02-uuid"
    kind: "loves"
    strength: 1.0

children:
  - id: "arc-awakening-uuid"
    type: arc
    name: "From Senate to Rebellion"
    summary: "Livia's transformation from privileged noble to rebel leader"

    children:
      - id: "beat-memory-flood-uuid"
        type: beat
        name: "The Memory Flood"
        summary: "Livia's past-life memories return during a Senate ceremony"

        content:
          - key: visual
            name: "Visual"
            value: |
              The Senate chamber. Livia stands frozen as golden light 
              fills her vision. Around her, time seems to slow.

          - key: narration
            name: "Narration"
            value: |
              A thousand lifetimes crash through her mind. She is Aya, 
              standing in the Great Pyramid. She is someone else, someone 
              older, someone yet to come.

          - key: duration
            name: "Duration"
            value: "03:45"

      - id: "beat-decision-uuid"
        type: beat
        name: "The Decision"
        summary: "Livia chooses rebellion over privilege"

Universe Hierarchy Example

metadata:
  formatVersion: "1.2"
  author: "Universe Creator"

id: "universe-11lives-uuid"
type: universe
name: "11 Lives"
summary: "Eleven souls across eleven epochs"

children:
  - id: "epoch-01-uuid"
    type: epoch
    name: "Epoch 01: Atlantis"

    children:
      - id: "char-aya-uuid"
        type: character
        name: "Aya"
        summary: "Atlantean priestess"

  - id: "epoch-02-uuid"
    type: epoch
    name: "Epoch 02: Rome"

    children:
      - id: "char-livia-uuid"
        type: character
        name: "Livia Mercuria"
        summary: "Roman rebel"

        relations:
          - targetId: "char-aya-uuid"
            kind: "reincarnation-of"

With Includes Example

metadata:
  formatVersion: "1.2"

id: "party-uuid"
type: group
name: "Adventuring Party"

children:
  - include: "/Characters/Aya.codex.yaml"
  - include: "/Characters/Livia.codex.yaml"
  - include: "/Characters/Marcus.codex.yaml"

Best Practices

1. Use name as Primary Identifier

name: "Livia Mercuria"        # βœ… Primary identifier
title: "The Rebel Senator"    # βœ… Optional display name

2. Multiline Strings with Pipe Format

body: |
  This is a long multiline string.

  It preserves line breaks and formatting.
  Perfect for narrative content.

3. Prioritize Clarity Over Brevity

# ❌ Too cryptic
attributes:
  - key: str
    value: 18

# βœ… Clear and explicit
attributes:
  - key: strength
    name: "Strength"
    value: 18
    dataType: int

4. Use Semantic Type Names

type: character      # βœ… Clear
type: location       # βœ… Clear
type: chapter        # βœ… Clear
type: beat           # βœ… Clear
type: arc            # βœ… Clear

5. Tag Comprehensively

tags:
  - 11-lives          # Series
  - epoch-02          # Period
  - protagonist       # Function
  - awakened          # Status
  - roman-era         # Context

6. Include DataTypes for Attributes

attributes:
  - key: strength
    value: 18
    dataType: int      # βœ… Explicit type

  - key: birth_date
    value: "75 BCE"
    dataType: date     # βœ… Explicit type

7. Document Versions Semantically

metadata:
  documentVersion: "1.0.0"    # Initial
  documentVersion: "1.1.0"    # Minor updates
  documentVersion: "2.0.0"    # Major revision

8. Clean String Whitespace

# ❌ Trailing spaces
name: "Livia Mercuria   "

# βœ… Clean strings
name: "Livia Mercuria"

Use the migration script's --reformat option to clean up whitespace.

9. Use Display Settings for Clean Presentation

# For lists, checklists, or structured data modules
display:
  breadcrumb: false  # Remove parent breadcrumb from titles
  icon: false       # Remove type icons for minimalist look
  type: false       # Remove type badges

# Children inherit these settings automatically
children:
  - name: "Item 1"
    # Automatically has breadcrumb=false, icon=false, type=false

Working with Git Projects

When using codex files in Git repositories:

File Organization

my-universe/
  β”œβ”€β”€ .codex-index.yaml          # Project index
  β”œβ”€β”€ Characters/
  β”‚   β”œβ”€β”€ Aya.codex.yaml
  β”‚   β”œβ”€β”€ Livia.codex.yaml
  β”‚   └── Marcus.codex.yaml
  β”œβ”€β”€ Locations/
  β”‚   β”œβ”€β”€ Atlantis.codex.yaml
  β”‚   └── Rome.codex.yaml
  └── images/
      β”œβ”€β”€ Aya/
      β”œβ”€β”€ Livia/
      └── Marcus/

Using Includes

# main.codex.yaml
metadata:
  formatVersion: "1.0"

id: "party-uuid"
type: group
name: "Main Characters"

children:
  - include: "/Characters/Aya.codex.yaml"
  - include: "/Characters/Livia.codex.yaml"
  - include: "/Characters/Marcus.codex.yaml"

Image Paths

# In /Characters/Aya.codex.yaml
image: "/images/Aya/portrait.jpg"

images:
  - url: "/images/Aya/concept-01.jpg"
    caption: "Concept art"
  - url: "/images/Aya/final.jpg"
    caption: "Final design"

Paths starting with / are relative to the Git repository root.


Migration from Legacy Formats

If you have files in older formats (with data wrappers or packetType fields), use the migration script:

# Migrate a single file
python scripts/migrate_codex_to_v1.py myfile.codex.yaml

# Migrate a directory
python scripts/migrate_codex_to_v1.py /path/to/codex/directory/

# Reformat an already-migrated file (clean strings, apply pipe format)
python scripts/migrate_codex_to_v1.py --reformat myfile.codex.yaml

# Dry run (see what would change without modifying files)
python scripts/migrate_codex_to_v1.py --dry-run myfile.codex.yaml

# Skip backups
python scripts/migrate_codex_to_v1.py --no-backup myfile.codex.yaml

The script: * βœ… Removes data wrapper * βœ… Creates metadata object * βœ… Moves format info to metadata.formatVersion * βœ… Handles title vs name intelligently * βœ… Cleans whitespace from strings * βœ… Applies pipe format (|) for multiline strings * βœ… Creates backups automatically (.backup extension)

Legacy Format Example

Before (Legacy V0.9):

packetType: entity
version: "0.9.0"
title: "Character"
data:
  id: "uuid"
  type: character
  name: "Hero"

After (V1.0+):

metadata:
  formatVersion: "1.2"

id: "uuid"
type: character
name: "Hero"

Validation

What the App Validates

When you upload or view a codex file, the app checks:

  • βœ… metadata object exists
  • βœ… metadata.formatVersion equals "1.0", "1.1", or "1.2"
  • ❌ Rejects files with data wrapper (legacy format)
  • ❌ Rejects files missing metadata

Required Validation

A V1.0+ parser MUST validate:

  1. Metadata Exists: metadata object must be present at root
  2. Format Version: metadata.formatVersion must equal "1.0", "1.1", or "1.2"
  3. No Data Wrapper: Files with data key at root must be rejected

Error Messages

Missing Metadata:

Invalid format: V1.0+ codex files must have a 'metadata' section.
Please migrate using scripts/migrate_codex_to_v1.py

Wrong Version:

Unsupported format version: 0.9.0. Only V1.0, V1.1, and V1.2 are supported.

Legacy Format:

Legacy format detected: Files with 'data' wrapper are not supported.
Please migrate using scripts/migrate_codex_to_v1.py

Optional Validation

Parsers MAY optionally validate:

  • UUID format (if id present)
  • ISO-8601 timestamps (if created/updated present)
  • Semantic versioning (if documentVersion present)
  • Relation target existence
  • Circular include detection

JSON Format Examples

All examples above use YAML, but here's the equivalent in JSON:

Simple Character (JSON)

{
  "metadata": {
    "formatVersion": "1.2",
    "documentVersion": "1.2.0",
    "author": "Author Name"
  },
  "id": "char-livia-uuid",
  "type": "character",
  "name": "Livia Mercuria",
  "summary": "Roman noblewoman turned rebel leader",
  "attributes": [
    {
      "key": "house",
      "name": "Noble House",
      "value": "Mercuria"
    },
    {
      "key": "strength",
      "name": "Strength",
      "value": 18,
      "dataType": "int"
    }
  ],
  "children": [
    {
      "id": "arc-uuid",
      "type": "arc",
      "name": "The Awakening"
    }
  ]
}

With Body (JSON)

{
  "metadata": {
    "formatVersion": "1.2"
  },
  "id": "char-aya-uuid",
  "type": "character",
  "name": "Aya",
  "body": "Born under the constellation of the Eternal Flame, Aya was marked from birth with the silver crescent upon her brow.\n\nAt sixteen, she discovered her prophetic sight during the Pyramid Meltdown."
}

Selective Include (JSON)

{
  "metadata": {
    "formatVersion": "1.2"
  },
  "id": "scene-uuid",
  "type": "scene",
  "name": "Act 1",
  "children": [
    {
      "include": "/Characters/Aya.codex.yaml"
    },
    {
      "include": {
        "file": "/Characters/Marcus.codex.yaml",
        "fields": ["summary", "image"]
      }
    }
  ]
}

Technical Specification

Conformance Levels

Level 1: Basic Parser * MUST validate metadata.formatVersion = "1.0", "1.1", or "1.2" * MUST reject files with data wrapper * MUST support all entity fields * MUST preserve order of children

Level 2: Full Parser * All Level 1 requirements * MUST support include directives (both string and object syntax) * MUST support selective field inclusion (V1.1) * MUST support both string and object tag formats (V1.2) * MUST resolve relative image paths * MUST handle both YAML and JSON

Level 3: Advanced Parser * All Level 2 requirements * MUST detect circular includes * MUST support relative path resolution * MUST render weighted tags with size variation (V1.2) * SHOULD validate UUIDs * SHOULD validate timestamps * SHOULD support relation validation

MIME Types

  • YAML: application/x-yaml or text/yaml
  • JSON: application/json

References

  • ISO 8601: Date and time format
  • RFC 4122: UUID specification
  • YAML 1.2: YAML specification
  • JSON: RFC 8259
  • Semantic Versioning: semver.org
  • SPDX: Software Package Data Exchange

Implementation Checklist

  • [ ] Parse metadata object
  • [ ] Validate formatVersion = "1.0"
  • [ ] Reject legacy data wrapper
  • [ ] Support all optional entity fields
  • [ ] Parse attributes array
  • [ ] Parse relations array
  • [ ] Parse children array (recursive)
  • [ ] Resolve include directives
  • [ ] Resolve relative image paths
  • [ ] Support YAML format
  • [ ] Support JSON format
  • [ ] Detect circular includes
  • [ ] Preserve child order

Resources

  • Git Projects Guide β€” Learn about Git Codex Projects for version-controlled storytelling
  • Migration Script β€” Located at scripts/migrate_codex_to_v1.py in the repository
  • JSON Schema β€” See codex_schema_v1.py for the full JSON Schema definition

Version History

V1.2 (November 30, 2025) * Enhanced tag array support with both string and object formats * Weighted tag display with size variation based on count values * Full rendering support for mixed tag arrays * Backwards compatible with V1.0 and V1.1

V1.1 (November 14, 2025) * Enhanced include directives with selective field inclusion * Support for relative path resolution (no slash or ./) * Object syntax for includes: { file: "...", fields: [...] } * Backwards compatible with V1.0

V1.0 (October 25, 2025) * Initial stable release * Perfect recursion * Metadata consolidation * Include directives * No data wrapper


License

This specification is licensed under CC BY-SA 4.0.


Summary

ChapterWise Codex Format V1.2 is a perfectly recursive, elegant format where:

βœ… Any part can be a standalone codex
βœ… No data wrapper β€” content at root
βœ… Metadata consolidates format info
βœ… Enhanced include directives β€” full or selective
βœ… Relative path support β€” flexible file organization
βœ… Full YAML and JSON support
βœ… Media-aware with image galleries
βœ… Flexible attributes and relations
βœ… Enhanced tagging β€” simple strings or weighted objects
βœ… Beautiful fractal structure

Start with a simple character, grow to a universe β€” the same format works at every level.