refactor: remove legacy types.ts file and update frontend to use new contracts feat: add applyActions function to manage action application and world state mutation chore: remove empty .gitkeep file from sqlite data directory refactor: update frontend App component to align with new API contracts and improve UX docs: revise project.md to reflect updated architecture and system requirements docs: update thoughts.md with current status, architecture decisions, and remaining checks
5.2 KiB
CharacterGarden — System Bible (MVP Architecture)
Purpose
CharacterGarden is a deterministic roleplay and simulation framework.
The system separates:
- Natural language (LLM / user input)
- Structured intent (parsed actions)
- Truth validation (rules engine)
- World state (persistent simulation)
The system MUST remain deterministic at the core.
Core Principle
The LLM is NOT the source of truth.
The LLM is used ONLY for:
- Parsing natural language → structured actions
- Generating narrative output
ALL validation, state changes, and rules are handled by deterministic code.
System Pipeline
All input MUST pass through the following pipeline:
-
PROSE INPUT
- Source: user or AI
- Format: free text
-
PARSER LAYER
- Converts text → structured actions
- May use LLM or rule-based parsing
- Output MUST follow strict schema (see Action Contract)
-
ACTION CONTRACT (STRICT)
- Only valid structured objects allowed past this point
- No free text allowed beyond this stage
-
TRUTH ENGINE
- Deterministic validation of actions
- No LLM usage allowed
- Returns validation results
-
WORLD STATE UPDATE
- Applies valid actions
- Rejects or partially applies invalid ones
-
RESPONSE GENERATION
- LLM converts results into narrative output
Hard Rule
The Truth Engine MUST NEVER:
- Parse natural language
- Infer missing intent
- Use probabilistic logic
- Call an LLM
If it does, the architecture is broken.
Action Contract (REQUIRED)
All actions MUST conform to this schema:
export type Action = {
actorId: string;
type: string;
targetId?: string;
locationId?: string;
metadata?: Record<string, any>;
};
No additional fields allowed unless explicitly added here.
Turn Structure
Each turn MUST be stored and processed as:
export type Turn = {
id: string;
rawText: string;
actions: Action[];
validation: ValidationResult[];
createdAt: number;
};
Validation Result Contract
export type ValidationResult = {
actionIndex: number;
success: boolean;
reason?: string;
message?: string;
};
Examples:
- "not_your_turn"
- "object_not_found"
- "door_locked"
Required System Layers
1. Parser Layer
Function:
parseTextToActions(text: string): Action[]
Responsibilities:
- Convert text → valid Action[]
- Resolve references ("he", "the door")
- May fail or return empty list
Allowed:
- LLM usage
- Heuristics
Not allowed:
- World state mutation
- Validation logic
2. Truth Engine
Function:
validateActions(actions: Action[], worldState: WorldState): ValidationResult[]
Responsibilities:
- Validate each action deterministically
- No mutation
3. World State Engine
Function:
applyActions(actions: Action[], results: ValidationResult[], worldState: WorldState): WorldState
Responsibilities:
- Apply ONLY valid actions
- Maintain consistency
World State Requirements
World state MUST:
- Be serializable
- Be versionable
- Support rollback
- Support branching
Database Requirements
Use SQLite.
Minimum tables:
- turns
- actions
- validation_results
- entities
- world_states
Each turn MUST be persisted.
Entity System
Entities MUST have stable IDs.
Example:
type Entity = {
id: string;
name: string;
type: string;
attributes: Record<string, any>;
};
Parser MUST resolve references to entity IDs.
Failure Handling
Failure is FIRST-CLASS.
Example:
{
success: false,
reason: "door_locked",
message: "The door cannot be opened."
}
The system MUST:
- Return failures clearly
- Allow LLM to narrate failures
- NOT silently fix invalid actions
LLM Adapter Rules
The LLM Adapter MUST:
- Never mutate world state
- Never validate actions
- Only transform data
Development Phases
Phase 1 — Contract Enforcement (CURRENT)
- Define Action, Turn, ValidationResult
- Refactor all code to use contracts
- Remove any free-text logic from truth engine
Phase 2 — Minimal Truth Engine
Implement test domain:
- Tic-tac-toe OR simple door system
Goal:
- Fully deterministic validation
- No LLM required for correctness
Phase 3 — Parser Improvement
- Add LLM parsing
- Add reference resolution
- Improve action extraction
Phase 4 — Memory System
- Persist entities
- Track history
- Add retrieval support
Non-Goals (For Now)
- No complex AI reasoning inside truth engine
- No autonomous agents
- No multi-agent planning
thoughts.md Requirement
Copilot MUST maintain a file:
/thoughts.md
After each major change, it MUST append:
- What was implemented
- Why it was implemented
- What assumptions were made
- What remains unclear
This is REQUIRED to maintain continuity across sessions.
Definition of Done (MVP)
The system is complete when:
- A user can input text
- It is parsed into structured actions
- Actions are validated deterministically
- World state updates correctly
- A narrative response is generated
WITHOUT requiring the LLM for correctness.
Final Rule
If any part of the system depends on the LLM to maintain logical correctness, the architecture has failed.
The LLM is an interface layer, not a reasoning authority.