6.5 KiB
6.5 KiB
thoughts.md
Current Status
- Scaffold complete:
charactergarden/folder structure created per spec section 9 - Core contracts defined in
app/src/types.ts: Entity, Action, Verb, ValidationResult, StateChange, GameEvent, Turn, Belief, Fact, Affordance, Summary docker-compose.ymlcreated; ollama service gated behind--profile llm(not required for MVP).env/.env.example/.gitignorein place- Container-first runtime files added: app/frontend Dockerfiles and
.dockerignores - Truth Engine implemented in
app/src/truthEngine.ts— pure function, no I/O, no LLMvalidate(actions, worldState)→ ValidationResultapplyChanges(worldState, changes)→ new WorldState (immutable)- All 8 verbs handled with explicit rejection reasons
movenow supports a built-in offscene room convention viacreateOffsceneRoom()latentEntities.tscan promote plausible personal items from belief to fact when the actor has carrying contextdb.tsadded with SQLite schema + persistence helpers forentities,events,turns,beliefs, andsummaries- Minimal Fastify server + app pipeline added with seeded world state and fallback parser
- Minimal Vite React inspector added for visual boot testing and state inspection
Current Architecture Decisions
- App: Node.js + Fastify + TypeScript
- Frontend: React + Vite + TypeScript
- Database: better-sqlite3 (synchronous, no ORM)
- Ollama is optional; system must work without it (per section 14)
Eventtype renamedGameEventin code to avoid collision with the DOMEventglobal- Latent personal items are gated by facts-derived affordances, not accepted directly from beliefs
- The offscene room is represented as a normal room entity with id
offscene - App and frontend should be run and validated through Docker Compose rather than host-installed Node
MVP Readiness (2026-04-23)
- Estimated completion: ~90%
- Completed against spec:
- Turn pipeline implemented end-to-end (input -> parse -> validate -> apply -> events -> narration)
- Truth Engine is authoritative for state mutation
- SQLite persistence for entities/events/turns/beliefs/summaries
- Dockerized app + frontend stack, with optional Ollama profile
- Minimal inspector UI for state/events/turns
- MVP world bounded to 2 rooms and <=3 characters
- Remaining to call MVP done:
- Run one clean boot smoke pass from current branch and record expected outputs in this file
- Add a short "MVP acceptance checklist" section and mark each contract as pass/fail
- Tighten fallback parser behavior for known starter prompts and ensure no regression on latent-item turns
MVP Acceptance Checklist
- PASS: Core contracts implemented (Entity, Action, ValidationResult, StateChange, GameEvent)
- PASS: Truth Engine is sole authority for state mutation
- PASS: Invalid actions produce explicit rejection reasons
- PASS: Turn flow wired end-to-end in app service
- PASS: SQLite tables for entities/events/turns/beliefs/summaries
- PASS: Dockerized app + frontend, no host Node dependency required
- PASS: MVP scope bounds respected (2 rooms, <=3 characters, limited verb set)
- PASS: Frontend inspector can submit turns and inspect state/events
- PASS: Latent personal-item flow works in runtime (
pull out my phone=> promoted + accepted) - PASS: Parser now fails gracefully with explicit rephrase guidance for unknown/underspecified input
Next Steps
- Execute and capture a final Docker boot smoke check (
/health,/api/state,/api/turnhappy path + latent-item turn) - Add explicit MVP acceptance checklist results here (contracts, scope limits, runtime constraints)
- Do a small parser-hardening pass for prompt coverage, then freeze MVP scope
- Defer non-MVP work (container-entity plausibility, richer narration, full LLM adapter)
Open Questions
- None currently blocking MVP implementation.
Resolved Decisions (2026-04-23)
- Room/location model: keep
locationas an entity attribute that points to another entity id. Rooms remain normal entities (type: room) and inventory usesinventory:<actor_id>. - MVP initial world: lock to 2 rooms (
garden,shed) and 2 characters (player,groundskeeper), plus static scene objects (gate,bench) and built-inoffsceneroom. - Latent personal-item plausibility: use actor attributes as the MVP source of truth (
clothed,pocket_count,has_bag,searched_empty). - Container/worn-item entities: defer to post-MVP. Add this as a planned extension, not a current gate for plausibility.
Follow-up Implications
- Keep truth rules keyed to entity
attributes.locationand avoid introducing a separate room-graph subsystem yet. - Keep fallback parser and truth engine behavior tuned to the locked MVP world and verb set.
- Add a backlog item for container-aware plausibility (
worn,container, nested inventory checks) after MVP boot/test milestone.
Turn Contract (Higher Stack)
- End-user turn response should always include:
narration(what happened)parser_feedbackwhen intent is unclear or underspecified- accepted/rejected action detail for debugger/inspector views
- UX rule: when
parser_feedbackis present, UI should explicitly surface it and encourage rephrasing.
LLM Prompting Contract (In-Environment)
- Added prompt builder in
app/src/llmAdapter.ts(buildActionExtractionPrompt) to enforce world-grounded extraction. - Prompt constraints:
- only allowed verbs
- only known entity ids from current world snapshot
- strict JSON output shape (
actions, optionalparser_feedback) - no freeform world mutation outside truth-engine validation
Session Notes
- 2026-04-23: Project started. Scaffold, type contracts, .gitignore, and .env.example created.
- 2026-04-23: Truth Engine implemented. Pure validation with per-verb handlers and immutable applyChanges helper.
- 2026-04-23: Added facts/affordances + latent entity resolver for improv-style personal items, plus offscene room support.
- 2026-04-23: Added SQLite schema module. Host
npm installis blocked bybetter-sqlite3on Windows Node 25, so runtime validation should happen inside Docker on an LTS Node image instead. - 2026-04-23: Added minimal backend/frontend boot slice so the project can be tested visually through Docker.
- 2026-04-23: Runtime smoke check passed with live services (
/healthok, state returned,look aroundaccepted,pull out my phoneaccepted with zero rejections). - 2026-04-23: Fallback parser hardened to return human-readable guidance on unclear input (e.g., unknown intent, missing take target, missing move destination) and suggest concrete rephrasing examples.