Skip to content

Latest commit

 

History

History
146 lines (118 loc) · 7.96 KB

File metadata and controls

146 lines (118 loc) · 7.96 KB

Interfaces and Modes

1. Enduring vision, principles, and rationale

An Interface is a durable, Universe-owned way for a user to interact with that Universe. It selects a stable installed mode, whose feature owns the behavior, specialized state, Drivers, routes, and presentation.

Initial mode identities are:

  • worldsharp.convo: a private Character direct-message surface;
  • worldsharp.roleplay: the shared multi-character roleplay workspace;
  • worldsharp.game: a game session;
  • worldsharp.social-feed: a Universe social application.

Mode IDs are qualified and stable; display names are not persisted as identity. Core should own common Interface identity, Universe ownership, descriptors, and cardinality rules. Extensions should not receive raw database access merely because they own a mode.

Generic Interface records contain common identity and shell metadata only. Messages, feed posts, Scene lifecycle, game state, and mode settings remain typed feature state. This avoids a generic JSON bucket that erases invariants.

Convo's enduring product intent is a familiar private DM, not a group Roleplay substitute. A Roleplay workspace may be durable or temporarily bounded as a Scene session. The bounded session's branch, summary, and review invariants should survive storage reuse without requiring a second chat workspace.

2. Proposed and future architecture, including alternatives

The shell should enumerate installed descriptors and persisted Interfaces without knowing every mode by name. Descriptors provide identity, display metadata, cardinality, and application-relative create/open routes. A complete generic mode service would enforce descriptor cardinality and coordinate creation while delegating specialized input and persistence to the feature.

Convo was originally specified as exactly one Character Instance. The current domain permits one or more, so "exactly one" is now an unresolved implementation gap or product decision rather than a current invariant. If the direct-message ideal is reaffirmed, Core/storage and import compatibility must enforce or explicitly migrate it; the UI alone is insufficient.

Social Feed is intended to be singleton per Universe. Convo and Roleplay may have multiple instances; a bounded Scene is a Roleplay lifecycle profile rather than another shell mode. Cardinality should ultimately be enforced at the Core/application boundary, not hidden in a creation page.

Personas should eventually support optional Interface grouping and filtering. Likewise, active, paused, ended, and archived distinctions should come from explicit lifecycle state rather than inferred timestamps.

Mode-specific settings should remain feature-owned. The pre-Interface Conversation storage name may continue as a transcript implementation detail, but it should not become the claim that every Interface is conversational.

3. Current implementation, status, and known gaps

The host registers mode descriptors at startup and exposes them through GET /api/interface-modes. The shell lists persisted conversation-backed Interfaces through GET /api/universes/{universeId}/interfaces. The descriptor registry is currently a catalogue, not a generic instance-creation service.

Mode ID Descriptor cardinality Current backing state
worldsharp.convo Multiple Conversation; at least one Character
worldsharp.roleplay Multiple Conversation; at least one Character
worldsharp.roleplay Multiple Conversation plus optional SceneInterface lifecycle state
worldsharp.social-feed Singleton WorldInterface plus Social Feed extension storage
worldsharp.game Multiple Preview descriptor only

WorldInterface persists common identity, Universe, mode, display name, archive state, and Character participant IDs for conversation-backed modes. Conversation also stores an optional Persona and mode ID. Descriptor cardinality is metadata; no generic service currently enforces it across all mode storage.

Conversation timelines

Narrative branching belongs inside a conversation-backed Interface, not in the shell Interface list and not in World Tracker. One visible Interface owns the complete ancestor/sibling/descendant family. A timeline forks from an explicit historical message, inherits the transcript through that point, and owns later messages independently.

Exactly one timeline is selected as the path being continued. Creating a fork selects it; choosing a path in the timeline drawer persists that choice; reopening the root Interface routes to it. Non-selected paths remain readable but reject settings changes, edits, messages, and generation. Heartbeats, actor presence candidate resolution, summaries/tracker pickers, and automatic Real-Time day close consider only selected paths.

History shared with a child timeline becomes read-only in its parent so later edits cannot rewrite an already-diverged future. Preparing or reviewing a day/Scene wrapup blocks selection changes. Completed, no-change, and discarded wrapups close their exact ranges: another path may be selected only if it still contains those wrapped boundary messages. Going farther back requires duplicating the Universe and rolling the copy back, because canonical world state may already depend on the omitted conversation history.

Manual whole-timeline freezing is no longer part of the normal workflow. The stored status and /freeze//canon-lock endpoints remain for old data and API compatibility. A selected frozen legacy path is read-only but may fork from its last wrapped boundary to recover an active future. Freezing does not apply World Tracker proposals, choose canonical world facts, or create a parallel world snapshot.

Native response swipes belong to the selected Convo timeline rather than the Interface list. The latest locally authored Character response can have alternate versions generated and selected without changing its message ID or adding ordinary transcript turns. Previous/next versions are shown inline; imported or autonomous source responses remain read-only provenance. Swipes are blocked for inherited, shared, wrapped, frozen, or non-selected history. Imported Marinara branch records that lack trustworthy parent/fork identifiers are preserved as labelled alternate Interfaces rather than silently discarded or falsely linked.

Existing child paths still have internal world_interfaces rows. GET /api/universes/{universeId}/interfaces exposes only family roots, with the selected path as its open-route target. The Interface's shell name remains stable while individual timelines may have their own labels.

Current bounded Roleplay/Scene lifecycle

A bounded Roleplay session (displayed as a Scene) owns a participant snapshot, transcript, optional Persona and location, source-Convo/message provenance, temporary branch and starting commit, logical start/end, exact message range, end summary, tracker run, and optional promoted Roleplay. It uses the same workspace as a durable Roleplay; SceneInterface is lifecycle state, not a second transcript surface.

States are Active, Paused, AwaitingSummaryReview, AwaitingReconstructionReview, Ended, and Discarded. A source must be a Convo in the same Universe. Direct Scene creation requires Real Time. Ending seals the exact Scene range and creates or injects a Scene summary. After summary review, World Tracker reconstruction runs on the same branch and range. Commit or discard closes and archives the bounded session. It is opened and operated through the shared Roleplay workspace and its roleplay-session API resources; there is no separate Scene interface or legacy Scene route.

Game remains a preview, not a playable implementation. Social Feed's store creates or reuses its singleton WorldInterface row and owns its specialized tables; this is feature-specific enforcement, not a generic cardinality service. There is no general mode-settings store, dynamic mode installation, shell topbar/tool contribution API, Persona grouping, or generic mode creation/ cardinality enforcement.