Skip to main content

Maintainer guide

This section is for people and coding agents changing the bundle itself. Plugin development explains how another plugin consumes or extends it; this guide explains how to modify it without breaking persisted stories, agent protocols, or DSH lifecycle behaviour.

Non-negotiable invariants​

  • World files are authored definitions. Mutable story state belongs to a session's SQLite database.
  • Events are immutable facts after sealing. A character's perceptions and beliefs may change without rewriting the event.
  • Knowledge is closed-world: absent relationship or entity-knowledge edges mean that the character does not know the entity.
  • Every state mutation performed by an agent crosses a validated tool boundary. World-authoring mutations require user approval.
  • Text delivery must not wait for record keeping, world consolidation, suggestions, off-stage action, or image generation.
  • Story time, not turn count or wall time, determines memory age.
  • Generated media is filesystem-first. Stable paths and embedded or sidecar metadata are the index of record.
  • Services, listeners, slots, routes, and timers must be registered through the Cordis context so hot reload disposes them.

Package ownership​

PackageOwns
dsh-roleplay-modelCanonical types, constants, and cross-package vocabulary; no I/O
@dsh-agentic-roleplay/stateSQLite schema and migrations, repositories, recall, record tools, snapshots
@dsh-agentic-roleplay/coreFilesystem worlds, UI, sessions, agent loop, prompts, import, images, HTTP API
dsh-agentic-roleplayBundle manifest and the roleplay agent preset

Do not redefine a model in both core and state. The private model package is a source dependency and must be fully bundled: inspect the generated JavaScript and declarations for dangling dsh-roleplay-model imports after build changes.

Where to change a feature​

Host code is organised by concern under packages/dsh-agentic-roleplay-core/src/host; browser features follow the same pattern under src/client. Shared wire contracts and pure path/id helpers belong in src/shared. State contracts live in packages/dsh-roleplay-state/src, with repositories separated from SQLite implementations. The complete world file schema is the exact authored-file contract; the World format section gives its task-oriented form.

A story-model feature is not complete until all affected layers agree:

  1. canonical model and constants;
  2. schema migration, row mapping, repository interface, and implementation;
  3. session population and snapshot/restore behaviour;
  4. record-edit wire format, parser, JSON Schema, read-back view, and lint;
  5. keeper and character briefs, recall/indexing, and game-master scene context;
  6. HTTP/client editing where applicable;
  7. fixtures, migration tests, repository tests, loop tests, and documentation.

Working safely​

Preserve unrelated working-tree changes. Use existing parsers and repository APIs rather than editing JSON or SQLite ad hoc. Read current source before relying on this guide: defaults and exact validation bounds are deliberately centralised in code. Avoid copying third-party plugin code; compatible behaviour may be studied and independently implemented.

Continue with Orchestration for the turn protocol or Testing and release for the completion checklist.