schema: add session_anchor_at to actor_profile for simulation clock
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
-- OTIVM Per-Player Database Schema
|
-- OTIVM Per-Player Database Schema
|
||||||
-- File: data/create_player_db.sql
|
-- File: data/create_player_db.sql
|
||||||
-- Version: OTIVM-III
|
-- Version: OTIVM-IV (schema version 4)
|
||||||
-- Status: Game schema — transitional, designed to be throw-away
|
-- Status: Game schema — transitional, designed to be throw-away
|
||||||
-- Replaces: data/saves/{session_id}.json (OTIVM-I/II)
|
-- Replaces: data/saves/{session_id}.json (OTIVM-I/II)
|
||||||
-- Parallel to: data/create_otivm_db.sql (TESSERA world substrate)
|
-- Parallel to: data/create_otivm_db.sql (TESSERA world substrate)
|
||||||
@@ -11,6 +11,12 @@
|
|||||||
-- value_true and value_perceived are always separate columns
|
-- value_true and value_perceived are always separate columns
|
||||||
-- confidence_tag is always a first-class column, never a comment
|
-- confidence_tag is always a first-class column, never a comment
|
||||||
--
|
--
|
||||||
|
-- Simulation clock: see docs/architecture/simulation-clock.md
|
||||||
|
-- session_anchor_at is the real UTC timestamp at which the player's
|
||||||
|
-- simulation clock started (set at first dispatch, NULL until then).
|
||||||
|
-- All simulated date arithmetic uses this field as the epoch anchor
|
||||||
|
-- per the integer constraint documented in simulation-clock.md.
|
||||||
|
--
|
||||||
-- When this schema is retired, it becomes a read-only layer
|
-- When this schema is retired, it becomes a read-only layer
|
||||||
-- readable by the Simulator via the existing API translation layer.
|
-- readable by the Simulator via the existing API translation layer.
|
||||||
-- The API is the universal wiring — this schema does not need to
|
-- The API is the universal wiring — this schema does not need to
|
||||||
@@ -21,15 +27,20 @@
|
|||||||
|
|
||||||
PRAGMA journal_mode = WAL;
|
PRAGMA journal_mode = WAL;
|
||||||
PRAGMA foreign_keys = ON;
|
PRAGMA foreign_keys = ON;
|
||||||
PRAGMA user_version = 3; -- OTIVM-III schema version
|
PRAGMA user_version = 4; -- OTIVM-IV schema version
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: actor_profile
|
-- TABLE: actor_profile
|
||||||
-- One row per actor. The static anchor.
|
-- One row per actor. The static anchor.
|
||||||
-- Created at session initialisation. Never updated — superseded
|
-- Created at session initialisation. Never updated — superseded
|
||||||
-- by a new row if background is changed (not currently possible
|
-- by a new row if background is changed (not currently possible
|
||||||
-- in OTIVM-III but the structure supports it).
|
-- in OTIVM-IV but the structure supports it).
|
||||||
-- ============================================================
|
--
|
||||||
|
-- session_anchor_at: NULL until first dispatch. Set once at the
|
||||||
|
-- moment the player fires their first venture. All simulation
|
||||||
|
-- clock arithmetic is relative to this timestamp.
|
||||||
|
-- See docs/architecture/simulation-clock.md Section 7.
|
||||||
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS actor_profile (
|
CREATE TABLE IF NOT EXISTS actor_profile (
|
||||||
actor_id TEXT NOT NULL, -- uuid, matches save file naming
|
actor_id TEXT NOT NULL, -- uuid, matches save file naming
|
||||||
@@ -40,12 +51,15 @@ CREATE TABLE IF NOT EXISTS actor_profile (
|
|||||||
actor_name TEXT NOT NULL, -- display name chosen by participant
|
actor_name TEXT NOT NULL, -- display name chosen by participant
|
||||||
epoch TEXT NOT NULL -- roman_14bce (Layer 3 code token)
|
epoch TEXT NOT NULL -- roman_14bce (Layer 3 code token)
|
||||||
DEFAULT 'roman_14bce',
|
DEFAULT 'roman_14bce',
|
||||||
schema_version INTEGER NOT NULL DEFAULT 3,
|
schema_version INTEGER NOT NULL DEFAULT 4,
|
||||||
recorded_at TEXT NOT NULL, -- ISO 8601 UTC
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC — row creation time
|
||||||
|
session_anchor_at TEXT, -- ISO 8601 UTC — first dispatch time
|
||||||
|
-- NULL until player fires first venture
|
||||||
|
-- Never updated after it is set
|
||||||
PRIMARY KEY (actor_id, recorded_at)
|
PRIMARY KEY (actor_id, recorded_at)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: actor_parameters
|
-- TABLE: actor_parameters
|
||||||
-- The core parameter table.
|
-- The core parameter table.
|
||||||
-- One row per parameter per actor per recorded moment.
|
-- One row per parameter per actor per recorded moment.
|
||||||
@@ -68,7 +82,7 @@ CREATE TABLE IF NOT EXISTS actor_profile (
|
|||||||
-- value columns are TEXT to support ordinal bands (low/medium/high),
|
-- value columns are TEXT to support ordinal bands (low/medium/high),
|
||||||
-- enums, floats, integers, and JSON structures without schema changes.
|
-- enums, floats, integers, and JSON structures without schema changes.
|
||||||
-- The parameter_token identifies what type to expect.
|
-- The parameter_token identifies what type to expect.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS actor_parameters (
|
CREATE TABLE IF NOT EXISTS actor_parameters (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -92,14 +106,14 @@ CREATE TABLE IF NOT EXISTS actor_parameters (
|
|||||||
CREATE INDEX IF NOT EXISTS idx_actor_parameters_current
|
CREATE INDEX IF NOT EXISTS idx_actor_parameters_current
|
||||||
ON actor_parameters (actor_id, parameter_token, superseded_at);
|
ON actor_parameters (actor_id, parameter_token, superseded_at);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: parameter_drift_log
|
-- TABLE: parameter_drift_log
|
||||||
-- Append-only event log of every parameter change.
|
-- Append-only event log of every parameter change.
|
||||||
-- What changed, why, what triggered it, old and new values.
|
-- What changed, why, what triggered it, old and new values.
|
||||||
-- The behavioral record. Rows are never deleted.
|
-- The behavioral record. Rows are never deleted.
|
||||||
-- This is the source of truth for the Simulator when it
|
-- This is the source of truth for the Simulator when it
|
||||||
-- reads this database as a read-only layer.
|
-- reads this database as a read-only layer.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS parameter_drift_log (
|
CREATE TABLE IF NOT EXISTS parameter_drift_log (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -120,11 +134,11 @@ CREATE TABLE IF NOT EXISTS parameter_drift_log (
|
|||||||
CREATE INDEX IF NOT EXISTS idx_drift_log_actor
|
CREATE INDEX IF NOT EXISTS idx_drift_log_actor
|
||||||
ON parameter_drift_log (actor_id, recorded_at);
|
ON parameter_drift_log (actor_id, recorded_at);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: ventures
|
-- TABLE: ventures
|
||||||
-- One row per venture (NEGOTIVM in Roman layer).
|
-- One row per venture (NEGOTIVM in Roman layer).
|
||||||
-- Status tracks the lifecycle. Outcome recorded on completion.
|
-- Status tracks the lifecycle. Outcome recorded on completion.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ventures (
|
CREATE TABLE IF NOT EXISTS ventures (
|
||||||
venture_id TEXT PRIMARY KEY, -- uuid
|
venture_id TEXT PRIMARY KEY, -- uuid
|
||||||
@@ -148,12 +162,17 @@ CREATE TABLE IF NOT EXISTS ventures (
|
|||||||
CREATE INDEX IF NOT EXISTS idx_ventures_actor
|
CREATE INDEX IF NOT EXISTS idx_ventures_actor
|
||||||
ON ventures (actor_id, status);
|
ON ventures (actor_id, status);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: venture_legs
|
-- TABLE: venture_legs
|
||||||
-- One row per leg (ITER in Roman layer).
|
-- One row per leg (ITER in Roman layer).
|
||||||
-- Indivisible unit of movement within a venture.
|
-- Indivisible unit of movement within a venture.
|
||||||
-- Cost components recorded separately for Simulator readability.
|
-- Cost components recorded separately for Simulator readability.
|
||||||
-- ============================================================
|
--
|
||||||
|
-- duration_days: integer simulated days per simulation-clock.md.
|
||||||
|
-- Must be a positive integer. Never a decimal.
|
||||||
|
-- Derived from duration_ms / MS_PER_SIM_DAY at write time.
|
||||||
|
-- See docs/architecture/simulation-clock.md Section 2.
|
||||||
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS venture_legs (
|
CREATE TABLE IF NOT EXISTS venture_legs (
|
||||||
leg_id TEXT PRIMARY KEY, -- uuid
|
leg_id TEXT PRIMARY KEY, -- uuid
|
||||||
@@ -163,14 +182,15 @@ CREATE TABLE IF NOT EXISTS venture_legs (
|
|||||||
destination_h3 TEXT NOT NULL, -- H3 cell ID (TESSERA-compatible)
|
destination_h3 TEXT NOT NULL, -- H3 cell ID (TESSERA-compatible)
|
||||||
mode TEXT NOT NULL, -- road | sea | river | overland
|
mode TEXT NOT NULL, -- road | sea | river | overland
|
||||||
vessel_type TEXT, -- navis_oneraria | actuaria | NULL if land
|
vessel_type TEXT, -- navis_oneraria | actuaria | NULL if land
|
||||||
duration_days REAL, -- actual duration (NULL until complete)
|
duration_days INTEGER, -- simulated days (INTEGER, never REAL)
|
||||||
|
-- NULL until leg completes
|
||||||
cost_vectura REAL, -- freight charge (VECTVRA)
|
cost_vectura REAL, -- freight charge (VECTVRA)
|
||||||
cost_portoria REAL, -- customs duty (PORTORIVM)
|
cost_portoria REAL, -- customs duty (PORTORIVM)
|
||||||
cost_other REAL, -- horreum, incidentals
|
cost_other REAL, -- horreum, incidentals
|
||||||
cost_total REAL, -- sum of above
|
cost_total REAL, -- sum of above
|
||||||
status TEXT NOT NULL -- planned | active | complete | failed
|
status TEXT NOT NULL -- planned | active | complete | failed
|
||||||
DEFAULT 'planned',
|
DEFAULT 'planned',
|
||||||
delay_days REAL, -- deviation from expected duration
|
delay_days INTEGER, -- deviation from expected duration (INTEGER)
|
||||||
delay_cause TEXT, -- weather | congestion | dispute | NULL
|
delay_cause TEXT, -- weather | congestion | dispute | NULL
|
||||||
recorded_at TEXT NOT NULL, -- ISO 8601 UTC — leg created
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC — leg created
|
||||||
started_at TEXT,
|
started_at TEXT,
|
||||||
@@ -181,13 +201,13 @@ CREATE TABLE IF NOT EXISTS venture_legs (
|
|||||||
CREATE INDEX IF NOT EXISTS idx_legs_venture
|
CREATE INDEX IF NOT EXISTS idx_legs_venture
|
||||||
ON venture_legs (venture_id, leg_sequence);
|
ON venture_legs (venture_id, leg_sequence);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: scenario_state
|
-- TABLE: scenario_state
|
||||||
-- Active and archived scenario parameters.
|
-- Active and archived scenario parameters.
|
||||||
-- Transient during active window, archived on close.
|
-- Transient during active window, archived on close.
|
||||||
-- Must not persist into actor_parameters as permanent values —
|
-- Must not persist into actor_parameters as permanent values —
|
||||||
-- scenario parameters are pressures, not conditions.
|
-- scenario parameters are pressures, not conditions.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS scenario_state (
|
CREATE TABLE IF NOT EXISTS scenario_state (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -206,7 +226,7 @@ CREATE TABLE IF NOT EXISTS scenario_state (
|
|||||||
CREATE INDEX IF NOT EXISTS idx_scenario_active
|
CREATE INDEX IF NOT EXISTS idx_scenario_active
|
||||||
ON scenario_state (actor_id, scenario_id, archived_at);
|
ON scenario_state (actor_id, scenario_id, archived_at);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: events
|
-- TABLE: events
|
||||||
-- Append-only chronological record of all simulation state
|
-- Append-only chronological record of all simulation state
|
||||||
-- changes. The atomic unit of history.
|
-- changes. The atomic unit of history.
|
||||||
@@ -214,7 +234,7 @@ CREATE INDEX IF NOT EXISTS idx_scenario_active
|
|||||||
-- This table is the substrate for the behavioral model —
|
-- This table is the substrate for the behavioral model —
|
||||||
-- when this database becomes a read-only Simulator layer,
|
-- when this database becomes a read-only Simulator layer,
|
||||||
-- this table is the primary read target.
|
-- this table is the primary read target.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS events (
|
CREATE TABLE IF NOT EXISTS events (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -240,13 +260,13 @@ CREATE INDEX IF NOT EXISTS idx_events_actor_time
|
|||||||
CREATE INDEX IF NOT EXISTS idx_events_type
|
CREATE INDEX IF NOT EXISTS idx_events_type
|
||||||
ON events (event_type, recorded_at);
|
ON events (event_type, recorded_at);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: background_starting_values
|
-- TABLE: background_starting_values
|
||||||
-- Seed data — the canonical starting parameter values for
|
-- Seed data — the canonical starting parameter values for
|
||||||
-- each of the six backgrounds, per parameter-registry.md.
|
-- each of the six backgrounds, per parameter-registry.md.
|
||||||
-- Read at actor initialisation to populate actor_parameters.
|
-- Read at actor initialisation to populate actor_parameters.
|
||||||
-- Never modified after initial insert.
|
-- Never modified after initial insert.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS background_starting_values (
|
CREATE TABLE IF NOT EXISTS background_starting_values (
|
||||||
background_id TEXT NOT NULL,
|
background_id TEXT NOT NULL,
|
||||||
@@ -259,11 +279,11 @@ CREATE TABLE IF NOT EXISTS background_starting_values (
|
|||||||
PRIMARY KEY (background_id, parameter_token)
|
PRIMARY KEY (background_id, parameter_token)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- SEED DATA: background_starting_values
|
-- SEED DATA: background_starting_values
|
||||||
-- Source: parameter-registry.md, section 1 (Actor Parameters)
|
-- Source: parameter-registry.md, section 1 (Actor Parameters)
|
||||||
-- Ordinal bands: low | medium | high | distinguished | extensive
|
-- Ordinal bands: low | medium | high | distinguished | extensive
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
INSERT OR IGNORE INTO background_starting_values VALUES
|
INSERT OR IGNORE INTO background_starting_values VALUES
|
||||||
-- FORMER LEGIONARY
|
-- FORMER LEGIONARY
|
||||||
@@ -350,13 +370,13 @@ INSERT OR IGNORE INTO background_starting_values VALUES
|
|||||||
('guild_scribe', 'litterae', 'high', 'high', 'indicated', 'full', NULL),
|
('guild_scribe', 'litterae', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
('guild_scribe', 'officia_burden', 'low', 'low', 'indicated', 'partial', NULL);
|
('guild_scribe', 'officia_burden', 'low', 'low', 'indicated', 'partial', NULL);
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- TABLE: schema_changelog
|
-- TABLE: schema_changelog
|
||||||
-- Documents schema version history.
|
-- Documents schema version history.
|
||||||
-- Required: if this database becomes a read-only Simulator
|
-- Required: if this database becomes a read-only Simulator
|
||||||
-- layer, the Simulator must be able to identify schema version
|
-- layer, the Simulator must be able to identify schema version
|
||||||
-- and adapt its reader accordingly.
|
-- and adapt its reader accordingly.
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS schema_changelog (
|
CREATE TABLE IF NOT EXISTS schema_changelog (
|
||||||
version INTEGER PRIMARY KEY,
|
version INTEGER PRIMARY KEY,
|
||||||
@@ -367,9 +387,10 @@ CREATE TABLE IF NOT EXISTS schema_changelog (
|
|||||||
INSERT OR IGNORE INTO schema_changelog VALUES
|
INSERT OR IGNORE INTO schema_changelog VALUES
|
||||||
(1, 'OTIVM-I: JSON save files (not SQLite — recorded here for continuity)', '2026-04-25T00:00:00Z'),
|
(1, 'OTIVM-I: JSON save files (not SQLite — recorded here for continuity)', '2026-04-25T00:00:00Z'),
|
||||||
(2, 'OTIVM-II: JSON save files with TESSERA map integration', '2026-04-28T00:00:00Z'),
|
(2, 'OTIVM-II: JSON save files with TESSERA map integration', '2026-04-28T00:00:00Z'),
|
||||||
(3, 'OTIVM-III: Per-player SQLite schema, parameter registry v1', '2026-05-02T00:00:00Z');
|
(3, 'OTIVM-III: Per-player SQLite schema, parameter registry v1', '2026-05-02T00:00:00Z'),
|
||||||
|
(4, 'OTIVM-IV: Add session_anchor_at to actor_profile for simulation clock','2026-05-02T00:00:00Z');
|
||||||
|
|
||||||
-- ============================================================
|
-- ================================================================
|
||||||
-- END OF SCHEMA
|
-- END OF SCHEMA
|
||||||
-- To initialise a player database:
|
-- To initialise a player database:
|
||||||
-- sqlite3 data/saves/{actor_id}.sqlite3 < data/create_player_db.sql
|
-- sqlite3 data/saves/{actor_id}.sqlite3 < data/create_player_db.sql
|
||||||
@@ -378,4 +399,9 @@ INSERT OR IGNORE INTO schema_changelog VALUES
|
|||||||
-- sqlite3 data/saves/{actor_id}.sqlite3 "PRAGMA integrity_check;"
|
-- sqlite3 data/saves/{actor_id}.sqlite3 "PRAGMA integrity_check;"
|
||||||
-- sqlite3 data/saves/{actor_id}.sqlite3 "SELECT COUNT(*) FROM background_starting_values;"
|
-- sqlite3 data/saves/{actor_id}.sqlite3 "SELECT COUNT(*) FROM background_starting_values;"
|
||||||
-- Expected: 72 rows (12 parameters × 6 backgrounds)
|
-- Expected: 72 rows (12 parameters × 6 backgrounds)
|
||||||
-- ============================================================
|
--
|
||||||
|
-- Note on venture_legs.duration_days and delay_days:
|
||||||
|
-- Declared INTEGER, not REAL. This enforces the integer clock
|
||||||
|
-- constraint from docs/architecture/simulation-clock.md.
|
||||||
|
-- A fractional value here is a schema violation.
|
||||||
|
-- ================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user