π 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
- Introduction
- Design Philosophy
- File Formats
- Basic Structure
- Metadata Object
- Entity Fields
- Content Structures
- Attributes Array
- Relations Array
- Children Array
- Include Directives
- Media Handling
- Tagging System
- Complete Examples
- Best Practices
- Working with Git Projects
- Migration from Legacy Formats
- Validation
- JSON Format Examples
- 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
metadataobject - Include directives β Embed external files at any level
- Maximum flexibility β Only
metadata.formatVersionis 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
- Simplicity: Minimize required fields, maximize flexibility
- Composability: Enable file inclusion and modular design
- Extensibility: Support arbitrary attributes and relations
- Human-Friendly: Optimize for YAML readability
- Machine-Parseable: Clean JSON representation
File Formats
YAML Format (Recommended)
.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βstringorarray
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/identifiertitleβstringβ Display title (optional alternative to name)keyβstringβ Human-readable slug for cross-references
Content
summaryβstringβ Brief description or taglinebodyβstringβ Main content body (supports markdown)contentβarrayβ Structured content objects (see below)
Organization
tagsβarrayβ Entity-level tags for cross-referencingattributesβarrayβ Key-value metadata pairsrelationsβarrayβ Links to other entitieschildrenβarrayβ Nested child entities (RECURSIVE!)
Media
imageβstringβ Primary image URLimagesβarrayβ Image galleryexternal_urlβstringβ External reference URLanimation_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 identifiernameβstringβ Human-readable labelvalueβ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 numberfloatβ Decimal numberbooleanβ True/false valuestringβ Text stringarrayβ List of valuesobjectβ Complex objectdateβ ISO-8601 date/timestampurlβ Web URLmarkdownβ 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 entitytargetKeyβstringβ Human-readable key of targetkindβstring(required) β Relationship typestrengthβnumberβ Intensity (0.0 to 1.0)reciprocalβbooleanβ Whether to create reverse relationattributesβ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
- Path Format: Absolute (
/path) or relative (pathor./path) - File Extension: Typically
.codex.yamlor.codex.json - Valid Codex: Included file must be valid V1.0+ codex
- Recursive: Included files can contain their own includes
- Circular Detection: Circular includes are detected and prevented
- Security: Paths cannot escape project directory
Resolution Process
When parser encounters an include:
- Detect Syntax: String (full) or object (selective)
- Resolve Path: Apply path resolution rules
- Load: Read the referenced file
- Parse: Parse as V1.0+ codex
- Filter (selective only): Extract specified fields
- Embed: Replace include directive with content
- Recurse: Process any includes in embedded content
Media Handling
Simple Image
image: "/images/characters/livia-portrait.jpg"
Image Gallery
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:
- β
metadataobject exists - β
metadata.formatVersionequals"1.0","1.1", or"1.2" - β Rejects files with
datawrapper (legacy format) - β Rejects files missing
metadata
Required Validation
A V1.0+ parser MUST validate:
- Metadata Exists:
metadataobject must be present at root - Format Version:
metadata.formatVersionmust equal"1.0","1.1", or"1.2" - No Data Wrapper: Files with
datakey 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
idpresent) - ISO-8601 timestamps (if
created/updatedpresent) - Semantic versioning (if
documentVersionpresent) - 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-yamlortext/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
metadataobject - [ ] Validate
formatVersion = "1.0" - [ ] Reject legacy
datawrapper - [ ] Support all optional entity fields
- [ ] Parse
attributesarray - [ ] Parse
relationsarray - [ ] Parse
childrenarray (recursive) - [ ] Resolve
includedirectives - [ ] 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.pyin the repository - JSON Schema β See
codex_schema_v1.pyfor 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.