feat: implement processTurn function to handle turn processing and world state updates
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
This commit is contained in:
578
project.md
578
project.md
@@ -1,367 +1,355 @@
|
||||
# CharacterGarden – AI-Oriented Design Spec (Copilot-Ready)
|
||||
# CharacterGarden — System Bible (MVP Architecture)
|
||||
|
||||
## 0. Purpose
|
||||
## Purpose
|
||||
|
||||
This document defines **hard contracts and system boundaries** for CharacterGarden.
|
||||
CharacterGarden is a deterministic roleplay and simulation framework.
|
||||
|
||||
Goal: enable an AI coding assistant (e.g. Copilot) to implement the system step-by-step without ambiguity.
|
||||
The system separates:
|
||||
|
||||
Core principle:
|
||||
* Natural language (LLM / user input)
|
||||
* Structured intent (parsed actions)
|
||||
* Truth validation (rules engine)
|
||||
* World state (persistent simulation)
|
||||
|
||||
> The application owns truth. The LLM only translates and narrates.
|
||||
The system MUST remain deterministic at the core.
|
||||
|
||||
---
|
||||
|
||||
## 1. System Overview
|
||||
## Core Principle
|
||||
|
||||
### Pipeline
|
||||
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:
|
||||
|
||||
1. PROSE INPUT
|
||||
|
||||
* Source: user or AI
|
||||
* Format: free text
|
||||
|
||||
2. PARSER LAYER
|
||||
|
||||
* Converts text → structured actions
|
||||
* May use LLM or rule-based parsing
|
||||
* Output MUST follow strict schema (see Action Contract)
|
||||
|
||||
3. ACTION CONTRACT (STRICT)
|
||||
|
||||
* Only valid structured objects allowed past this point
|
||||
* No free text allowed beyond this stage
|
||||
|
||||
4. TRUTH ENGINE
|
||||
|
||||
* Deterministic validation of actions
|
||||
* No LLM usage allowed
|
||||
* Returns validation results
|
||||
|
||||
5. WORLD STATE UPDATE
|
||||
|
||||
* Applies valid actions
|
||||
* Rejects or partially applies invalid ones
|
||||
|
||||
6. 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:
|
||||
|
||||
```ts
|
||||
export type Action = {
|
||||
actorId: string;
|
||||
type: string;
|
||||
targetId?: string;
|
||||
locationId?: string;
|
||||
metadata?: Record<string, any>;
|
||||
};
|
||||
```
|
||||
Prose Input
|
||||
→ Intent Extraction
|
||||
→ Canonical Actions
|
||||
→ Truth Engine Validation
|
||||
→ State Changes + Events
|
||||
→ Memory Storage
|
||||
→ Narration Output
|
||||
|
||||
No additional fields allowed unless explicitly added here.
|
||||
|
||||
---
|
||||
|
||||
## Turn Structure
|
||||
|
||||
Each turn MUST be stored and processed as:
|
||||
|
||||
```ts
|
||||
export type Turn = {
|
||||
id: string;
|
||||
rawText: string;
|
||||
actions: Action[];
|
||||
validation: ValidationResult[];
|
||||
createdAt: number;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Contracts (STRICT)
|
||||
## Validation Result Contract
|
||||
|
||||
### 2.1 Entity
|
||||
|
||||
```
|
||||
Entity {
|
||||
id: string
|
||||
type: string
|
||||
name: string
|
||||
attributes: object
|
||||
}
|
||||
```ts
|
||||
export type ValidationResult = {
|
||||
actionIndex: number;
|
||||
success: boolean;
|
||||
reason?: string;
|
||||
message?: string;
|
||||
};
|
||||
```
|
||||
|
||||
### 2.2 Action (Canonical)
|
||||
Examples:
|
||||
|
||||
```
|
||||
Action {
|
||||
actor: string (entity id)
|
||||
verb: string (enum)
|
||||
target?: string (entity id)
|
||||
params?: object
|
||||
}
|
||||
```
|
||||
|
||||
Allowed verbs (MVP):
|
||||
|
||||
```
|
||||
move, open, close, take, drop, use, inspect, speak
|
||||
```
|
||||
|
||||
### 2.3 Validation Result
|
||||
|
||||
```
|
||||
ValidationResult {
|
||||
accepted: Action[]
|
||||
rejected: { action: Action, reason: string }[]
|
||||
state_changes: StateChange[]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 State Change
|
||||
|
||||
```
|
||||
StateChange {
|
||||
entity_id: string
|
||||
field: string
|
||||
old_value: any
|
||||
new_value: any
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 Event
|
||||
|
||||
```
|
||||
Event {
|
||||
id: string
|
||||
turn: number
|
||||
action: Action
|
||||
result: "success" | "fail"
|
||||
timestamp: number
|
||||
}
|
||||
```
|
||||
* "not_your_turn"
|
||||
* "object_not_found"
|
||||
* "door_locked"
|
||||
|
||||
---
|
||||
|
||||
## 3. Truth Rules
|
||||
## Required System Layers
|
||||
|
||||
1. Only the **Truth Engine** can modify world state
|
||||
2. LLM output is NEVER directly trusted
|
||||
3. Every state change must be traceable to an Event
|
||||
4. Invalid actions must return explicit failure reasons
|
||||
### 1. Parser Layer
|
||||
|
||||
---
|
||||
|
||||
## 4. Memory Model
|
||||
|
||||
Memory is NOT a single blob.
|
||||
|
||||
### Types
|
||||
|
||||
#### 4.1 Turn
|
||||
|
||||
Raw input/output
|
||||
|
||||
#### 4.2 Event
|
||||
|
||||
Accepted or rejected actions
|
||||
|
||||
#### 4.3 Fact
|
||||
|
||||
Current world state (derived, not duplicated)
|
||||
|
||||
#### 4.4 Belief
|
||||
Function:
|
||||
|
||||
```ts
|
||||
parseTextToActions(text: string): Action[]
|
||||
```
|
||||
Belief {
|
||||
entity_id: string
|
||||
claim: string
|
||||
confidence: number
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.5 Summary
|
||||
|
||||
Compressed narrative context
|
||||
|
||||
---
|
||||
|
||||
## 5. Services
|
||||
|
||||
### 5.1 App (Core Service)
|
||||
|
||||
Responsibilities:
|
||||
|
||||
* orchestrate turns
|
||||
* call LLM (optional)
|
||||
* run truth engine
|
||||
* manage memory
|
||||
* Convert text → valid Action[]
|
||||
* Resolve references ("he", "the door")
|
||||
* May fail or return empty list
|
||||
|
||||
Tech: Node.js (Express or Fastify)
|
||||
Allowed:
|
||||
|
||||
* LLM usage
|
||||
* Heuristics
|
||||
|
||||
Not allowed:
|
||||
|
||||
* World state mutation
|
||||
* Validation logic
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Truth Engine (Module inside App)
|
||||
### 2. Truth Engine
|
||||
|
||||
Responsibilities:
|
||||
Function:
|
||||
|
||||
* validate actions
|
||||
* enforce rules
|
||||
* apply state changes
|
||||
* emit events
|
||||
|
||||
NO LLM USAGE
|
||||
|
||||
---
|
||||
|
||||
### 5.3 LLM Adapter (Optional)
|
||||
|
||||
Responsibilities:
|
||||
|
||||
* extract actions from prose
|
||||
* resolve references
|
||||
* generate narration
|
||||
* summarize memory
|
||||
|
||||
Backend: Ollama
|
||||
|
||||
---
|
||||
|
||||
### 5.4 Frontend
|
||||
|
||||
Responsibilities:
|
||||
|
||||
* send input
|
||||
* display output
|
||||
* optionally inspect state/events
|
||||
|
||||
Minimal React or Vue app
|
||||
|
||||
---
|
||||
|
||||
## 6. Turn Flow (IMPLEMENT EXACTLY)
|
||||
|
||||
```
|
||||
1. Receive user input (string)
|
||||
2. Store raw turn
|
||||
3. Extract actions (LLM or fallback parser)
|
||||
4. Validate actions (truth engine)
|
||||
5. Apply accepted changes
|
||||
6. Store events
|
||||
7. Generate narration
|
||||
8. Return response
|
||||
```ts
|
||||
validateActions(actions: Action[], worldState: WorldState): ValidationResult[]
|
||||
```
|
||||
|
||||
Responsibilities:
|
||||
|
||||
* Validate each action deterministically
|
||||
* No mutation
|
||||
|
||||
---
|
||||
|
||||
## 7. Storage
|
||||
### 3. World State Engine
|
||||
|
||||
### SQLite (MVP)
|
||||
Function:
|
||||
|
||||
Tables:
|
||||
```ts
|
||||
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:
|
||||
|
||||
* entities
|
||||
* events
|
||||
* turns
|
||||
* beliefs
|
||||
* summaries
|
||||
* actions
|
||||
* validation_results
|
||||
* entities
|
||||
* world_states
|
||||
|
||||
File location:
|
||||
Each turn MUST be persisted.
|
||||
|
||||
```
|
||||
/data/sqlite/app.db
|
||||
---
|
||||
|
||||
## Entity System
|
||||
|
||||
Entities MUST have stable IDs.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
type Entity = {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
attributes: Record<string, any>;
|
||||
};
|
||||
```
|
||||
|
||||
Parser MUST resolve references to entity IDs.
|
||||
|
||||
---
|
||||
|
||||
## 8. Docker Design
|
||||
## Failure Handling
|
||||
|
||||
### Services
|
||||
Failure is FIRST-CLASS.
|
||||
|
||||
```
|
||||
services:
|
||||
app
|
||||
frontend
|
||||
ollama (optional)
|
||||
Example:
|
||||
|
||||
```ts
|
||||
{
|
||||
success: false,
|
||||
reason: "door_locked",
|
||||
message: "The door cannot be opened."
|
||||
}
|
||||
```
|
||||
|
||||
### Principles
|
||||
The system MUST:
|
||||
|
||||
* No host dependencies beyond Docker
|
||||
* Persist only `/data`
|
||||
* Use `.env` for config
|
||||
* No hidden setup scripts
|
||||
* Return failures clearly
|
||||
* Allow LLM to narrate failures
|
||||
* NOT silently fix invalid actions
|
||||
|
||||
---
|
||||
|
||||
## 9. Folder Structure
|
||||
## 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:
|
||||
|
||||
```
|
||||
charactergarden/
|
||||
docker-compose.yml
|
||||
.env
|
||||
app/
|
||||
frontend/
|
||||
data/
|
||||
sqlite/
|
||||
/thoughts.md
|
||||
```
|
||||
|
||||
---
|
||||
After each major change, it MUST append:
|
||||
|
||||
## 10. MVP Scope
|
||||
* What was implemented
|
||||
* Why it was implemented
|
||||
* What assumptions were made
|
||||
* What remains unclear
|
||||
|
||||
STRICT LIMITS:
|
||||
|
||||
* 1–2 rooms
|
||||
* ≤3 characters
|
||||
* ≤10 actions
|
||||
* no complex AI autonomy
|
||||
* no multi-agent loops yet
|
||||
This is REQUIRED to maintain continuity across sessions.
|
||||
|
||||
---
|
||||
|
||||
## 11. Non-Goals (DO NOT BUILD YET)
|
||||
## Definition of Done (MVP)
|
||||
|
||||
* microservices
|
||||
* distributed systems
|
||||
* plugin frameworks
|
||||
* advanced agent loops
|
||||
* cloud dependencies
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 12. Development Workflow Rule
|
||||
## Final Rule
|
||||
|
||||
A root-level file named `thoughts.md` must exist and be maintained throughout development.
|
||||
If any part of the system depends on the LLM to maintain logical correctness,
|
||||
the architecture has failed.
|
||||
|
||||
Purpose of `thoughts.md`:
|
||||
|
||||
* record current implementation status
|
||||
* record the next planned steps
|
||||
* record blockers, assumptions, and unresolved questions
|
||||
* summarize architectural decisions already made
|
||||
* preserve continuity across editor sessions or context loss
|
||||
|
||||
Rules for `thoughts.md`:
|
||||
|
||||
* update it after each meaningful implementation step
|
||||
* keep entries concise and factual
|
||||
* do not use it for chain-of-thought dumping or vague brainstorming
|
||||
* use it as a project progress log and working memory
|
||||
* when resuming work, review `thoughts.md` first before making changes
|
||||
* when changing architecture, record what changed and why
|
||||
* when a task is incomplete, note exactly what remains
|
||||
|
||||
Recommended structure:
|
||||
|
||||
```md
|
||||
# thoughts.md
|
||||
|
||||
## Current Status
|
||||
- what is implemented
|
||||
- what is partially implemented
|
||||
- what is broken or unverified
|
||||
|
||||
## Current Architecture Decisions
|
||||
- key decisions and constraints
|
||||
|
||||
## Next Steps
|
||||
- ordered checklist of immediate tasks
|
||||
|
||||
## Open Questions
|
||||
- unresolved design or implementation questions
|
||||
|
||||
## Session Notes
|
||||
- short dated notes describing recent progress
|
||||
```
|
||||
|
||||
Copilot instruction:
|
||||
|
||||
> Before starting work, read `thoughts.md`. After completing any meaningful change, update `thoughts.md` to reflect current status, next steps, and any unresolved issues.
|
||||
|
||||
## 13. Development Order
|
||||
|
||||
1. Define entities + actions
|
||||
2. Implement truth engine
|
||||
3. Add SQLite persistence
|
||||
4. Build API endpoints
|
||||
5. Add minimal UI
|
||||
6. Add LLM integration
|
||||
|
||||
---
|
||||
|
||||
## 14. Key Rule
|
||||
|
||||
> If the system works without an LLM, the architecture is correct.
|
||||
|
||||
---
|
||||
|
||||
## 15. Expected Behavior
|
||||
|
||||
* deterministic state
|
||||
* explainable failures
|
||||
* replayable sessions
|
||||
* inspectable memory
|
||||
|
||||
---
|
||||
|
||||
## 16. Future Extensions (NOT NOW)
|
||||
|
||||
* branching timelines
|
||||
* advanced belief systems
|
||||
* multi-agent arbitration
|
||||
* long-term memory compression
|
||||
|
||||
---
|
||||
|
||||
## END SPEC
|
||||
The LLM is an interface layer, not a reasoning authority.
|
||||
|
||||
Reference in New Issue
Block a user