You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constcanon=newCanonReader('./canon');constentities=canon.getAllEntities();// All 10 JSONL files mergedconstkingdoms=canon.getEntitiesByType('kingdom');// Single typeconstentity=canon.getEntity('kingdom-of-eldoria');// By slugconstgraph=canon.buildGraph();// Dynamic graph from all relationshipsconststate=canon.getLatestMemory();// Last line of journal.jsonl
Graph is never stored as a file. It is constructed at load time by iterating entity relationship arrays. For 300 entities this takes < 50ms.
constchain=newFallbackChain([{provider: newOpenAIProvider(key),priority: 1},{provider: newGroqProvider(key),priority: 2},{provider: newGeminiProvider(key),priority: 3},]);constresult=awaitchain.execute(request);// Tries providers in priority order.// On failure: logs warning, tries next.// On all fail: returns null, pipeline aborts entity.
4. GENERATION PIPELINE (LAYER 3)
4.1 Pipeline Stages
Stage 1: SELECTOR
Purpose: Pick what to generate next
Input: generation-plan.json (weights + focus)
Output: { type: "kingdom", count: 1 }
Stage 2: CONTEXT ASSEMBLER
Purpose: Build the prompt context from canon
Input: entity type, world memory, rules, neighbor entities
Output: Assembled prompt + system prompt
Stage 3: GENERATOR
Purpose: Call AI provider to generate entity content
Input: prompts
Output: Raw AI response text
Stage 4: POST-PROCESSOR
Purpose: Clean and structure the AI output
Actions:
- Parse structured fields from AI output
- Resolve {{entity}} references
- Normalize names against naming registry
- Extract implicit relationships
Output: Structured Entity object
Stage 5: VALIDATOR
Purpose: Check generated entity against canon
Checks (warning-based, non-blocking):
- Name collision check
- Relationship target validity
- Timeline consistency
- Required field completeness
- Anti-slop pattern detection
Output: ValidationReport { warnings[], errors[] }
Stage 6: COMMITTER
Purpose: Write to canon + content
Actions:
- Append entity to entities/{type}.jsonl
- Generate content/{type}/{slug}.md
- Update naming-registry.json
- Append new world memory snapshot
- Update generation-plan weights
Output: Write results
Stage 7: LINKER (separate pass, non-pipeline)
Purpose: Refresh internal links across all content
Actions:
- Read all entities
- For each: read relationships → generate link markdown
- Write/update content markdown with link sections
4.2 Context Assembly Strategy
The prompt context is tightly scoped to prevent AI confusion:
SYSTEM PROMPT:
[world-core rules]
[anti-slop-rules]
[tone-guide]
USER PROMPT:
Generate a new {type} for Aetherion Archive.
CURRENT WORLD STATE:
[world-memory latest snapshot - condensed to 15 lines]
EXISTING CANON (neighbors only):
[entities within 1-2 hops of proposed entity]
[max 10 entities, summarized]
REQUIRED RELATIONSHIPS:
[must link to: {list of specific existing entities}]
NAMING RULES:
[naming patterns for this entity type]
[used names that must not be duplicated]
Generate a {type} named {name} with:
- Relationships to the required entities above
- Unique lore that doesn't contradict existing canon
- Anti-slop compliance (no generic fantasy tropes)
4.3 Weighted Type Selection
functionpickNextEntityType(plan: GenerationPlan): EntityType{constscores=Object.entries(plan.distribution).map(([type,data])=>{constgap=data.target-data.current;constscore=Math.max(0,gap)*data.weight;return{ type, score };});// Apply focus multiplier if activeif(plan.currentFocus){scores.forEach(s=>{if(plan.currentFocus.entityTypes.includes(s.type)){s.score*=2.5;// Focus types get 2.5x priority}});}returnweightedRandom(scores);}
5. SEO ENGINE (LAYER 4)
5.1 Topical Clustering
Three pillar clusters derived from entity types:
Cluster
Pillar Type
Cluster Types
SEO Strategy
World & Power
kingdoms
cities, factions, events
Geographic + political keywords
Divine & Magic
gods
religions, artifacts, spells
Mystical + power keywords
Beings & Conflict
races
monsters, events
Creature + conflict keywords
5.2 Schema.org Mapping
Entity Type
Schema.org Type
kingdom
AdministrativeArea
faction
Organization
race
Thing
god
Person + ReligiousLeadership
artifact
Product + CreativeWork
spell
CreativeWork
event
Event
monster
Thing + BioChemEntity
city
City
religion
Organization
5.3 Internal Linking Rules
1. All links originate from entity relationship arrays
2. No keyword-based auto-linking
3. Every entity page MUST render ≥ 5 relationship links
4. Links must be bidirectional (enforced by entity graph)
5. Link text = relationship label, not keyword
6. "Related entities" section = 2-hop neighbors from graph traversal
7. Breadcrumbs: Entity Type > Entity Name
6. STATIC SITE (LAYER 5)
6.1 Page Types
Route
Template
Content Source
/
index.astro
world-core + featured entities
/[type]
listing.astro
All entities of that type
/[type]/[slug]
entity.astro
Single entity + relationships
/timeline
timeline.astro
timeline.jsonl
/sitemap.xml
sitemap.xml.ts
All entities, split by type
6.2 Build Pipeline
Astro build:
1. Load all canon (entities + timeline + rules)
2. Build entity graph from relationship arrays
3. Generate all entity pages from canon data
4. Compute internal links for each page
5. Inject Schema.org JSON-LD for each page
6. Generate listing pages for each type
7. Generate timeline page
8. Generate sitemap (split by type)
9. Output static HTML/CSS to /dist
10. Deploy dist/ to Cloudflare Pages