From a2a079a5e70e26db37207800a34cb69f35ae7c51 Mon Sep 17 00:00:00 2001 From: TheRON Date: Sun, 3 May 2026 10:12:28 -0400 Subject: [PATCH] Initial commit --- docs/Roadmap-OTIVM-IV.md | 501 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 docs/Roadmap-OTIVM-IV.md diff --git a/docs/Roadmap-OTIVM-IV.md b/docs/Roadmap-OTIVM-IV.md new file mode 100644 index 0000000..bced0a3 --- /dev/null +++ b/docs/Roadmap-OTIVM-IV.md @@ -0,0 +1,501 @@ +# OTIVM-IV — Roadmap +### Date: 2026-05-03 +### Status: APPROVED — implementation begins after this document is committed +### Supersedes: roadmap-OTIVM-IV-draft.md + +--- + +## 0. What OTIVM-IV is, in one sentence + +OTIVM-IV replaces the idler interface with a situation instrument: +a screen that shows the merchant's full economic and social state, +structured costs, active decisions, and transformation economics — +the first thing a Simulator participant would recognise as their +working environment. + +--- + +## 1. Why the roadmap definition changed + +The original roadmap defined OTIVM-IV as "The Seasons" — real +dispatch durations, DWD weather, route closures. That definition +is superseded by two decisions: + +1. Weather from Berlin projected onto the Roman Mediterranean is not + a meaningful signal until the restoration layer (HYDE 3.3 + KK10) + and route corridor H5 hexes exist. Weather belongs in a later + release. + +2. The game is evolving toward the Simulator, not toward a richer + idler. The interface must evolve with it. + +OTIVM-IV therefore covers: interface architecture, economic model, +transformation routes, and barter mechanics. The roadmap's Section 2 +narrative for OTIVM-IV is superseded. Sections 1, 3, and 5 are +unchanged. + +--- + +## 2. Governing constraints — gates, not preferences + +**No throw-away code.** Every component, route, and data structure +built in OTIVM-IV must be legible from the Simulator. If it would +not exist in the Simulator interface, it does not get built now. + +**File growth control.** Before any new file is created: can this +live inside an existing file? Consolidation is preferred over +addition. The JSON configuration pattern is the primary tool for +controlling file growth — screens are data, not code. + +**Vendored dependencies.** No CDN references. Every library is +pinned to a specific version, installed via npm with a fixed version +string. The build must be reproducible from `npm install` alone. +- Bootstrap 5.3.3 (MIT — local copy permitted) +- Bootstrap Icons 1.11.3 (MIT — local copy permitted) + +**Painstaking precision.** This document is the gate. No file is +touched that is not named in Section 7. No feature is built that +is not specified here. Design is complete before implementation +begins. + +**One file. One step. One confirmation.** Every change follows this +sequence without exception. When a commit requires two files, both +must be fully specified in the instruction header before Claude Code +touches anything. + +--- + +## 3. The shell architecture + +The central architectural decision of OTIVM-IV is the separation +of structure from content. The shell is built once and never changes. +Content is driven by JSON configuration files committed to the repo. + +### The shell + +The shell consists of three components written once: + +**`Shell.jsx`** — the persistent sidebar containing the application +title, the context dropdown, and the save token. The dropdown reads +`src/config/contexts.json`. Selecting a context loads the +corresponding `context-{id}.json`, applies the specified layout +grid, and renders the appropriate screen component. The sidebar +never grows — new contexts appear in the dropdown automatically. + +**`Section.jsx`** — a generic panel renderer. It receives a section +definition from the context JSON and renders the appropriate +sub-component based on `type`. It does not know what it is showing. + +**`contexts.json`** — the dropdown definition. One entry per +context. Each entry names the context, its layout type, and its +sub-items. Adding a new context in a future release requires one +new JSON file and one thin screen file — nothing else changes. + +### The layout types + +Four layout types, specified in context JSON, applied by Shell.jsx: + +| Layout | Grid | Use | +|---|---|---| +| `single` | one full-width column | simple reference screens | +| `two-col` | 40% left + 60% right | decision screens | +| `three-col` | 25% + 50% + 25% | dense instrument screens | +| `map` | 30% sidebar + 70% canvas | map context | + +### The section types + +Section.jsx renders one panel. Type determines sub-component: + +| Type | Renders | +|---|---| +| `parameter-list` | actor_parameters rows | +| `cost-table` | cost items with source citations | +| `drift-log` | parameter_drift_log entries | +| `status-block` | key/value status pairs | +| `action-bar` | action buttons | +| `route-list` | trade route cards with cost breakdowns | +| `map-canvas` | TESSERA fog-of-war map | +| `text-block` | narrative text, collapsible | + +New section types are added by extending Section.jsx only — no +shell changes required. + +### Why this controls file growth + +A session that adds a new context touches exactly two files: +`src/config/context-X.json` and `src/screens/X.jsx`. The shell, +the server, the existing contexts — untouched. The screen file is +thin because it delegates all rendering to Section.jsx. The JSON +file is not code and does not need to be debugged. + +--- + +## 4. The three contexts + +### ACTOR +*Who am I and where do I stand?* + +Layout: `three-col` + +The Simulator's Constructor profile in Roman dress. Shows: +- Background identity (from `actor_profile.background_id`) +- Twelve parameters with `value_perceived` band and `confidence_tag` +- Parameters where `value_true ≠ value_perceived` are visually flagged +- Auctoritas in three faces: `value_true`, `value_perceived`, + `value_social` +- `liquiditas` with structured breakdown: available, committed, + next otium cost +- Officia burden prominently shown +- Recent drift log entries + +The ACTOR context replaces the Prologue tab. Once a background is +chosen, the background selection UI appears within the ACTOR context +(`background_id = null` state). After selection, the ACTOR context +shows the read-only instrument view permanently. + +### FORUM +*What decisions are in front of me?* + +Layout: `two-col` + +The decision surface. Shows: +- Active venture status (route, cargo, leg, elapsed sim days, + expected return) — a dispatch record, not a progress bar +- Trade routes with full cost breakdown visible: + vectura / portoria / other / revenue / net +- Transformation routes (new in OTIVM-IV): routes where the + merchant ships a raw good and receives a transformed good +- Expenditure decisions: periodic costs debited per otium cycle +- Otium shown as a deliberate investment, not a rest button +- Journal as a collapsible panel within FORUM, not a separate screen + +### MAP +*Where have I been?* + +Layout: `map` + +Unchanged in function from OTIVM-III. The fog-of-war SVG map +renders from TESSERA H7 data via `/api/map/:h5/:epoch`. The MAP +context is a thin wrapper around the existing `Map.jsx` component. +No map code changes in OTIVM-IV. + +--- + +## 5. The economic model + +### Foundation documents + +Two calibration documents are committed to `docs/economy/`: +- `cost-calibration-model.md` — ceramic cup baseline, periodic costs, + reference wages +- `cost-calibration-additional-goods.md` — garum, grain, amber, + marble capital + +These are the permanent calibration substrate. All cost constants +derive from them. + +### Five good patterns + +Every good in OTIVM is one of five patterns: + +| Pattern | Example | Core equation | +|---|---|---| +| `batch_craft` | Ceramic cup | raw + labour + kiln + overhead + market | +| `perishable_batch` | Garum | raw + salt + vessel + time + spoilage + quality | +| `bulk_staple` | Grain | origin + freight + storage + loss + low margin | +| `import_luxury` | Amber | acquisition + risk + information asymmetry + markup | +| `commission_heavy` | Marble capital | block + labour + heavy transport + agent fee + risk | + +### Periodic operating costs — implemented in OTIVM-IV + +Three named trigger types, debited per otium cycle: + +``` +OTIUM_ACCESS_FEE_DN = 2.00 // otium_access_fee trigger +PERSONAL_MAINTENANCE_DN = 4.00 // personal_maintenance trigger +OFFICIA_OBLIGATION_DN = 2.00 // officia_obligation trigger +OTIUM_CYCLE_TOTAL_DN = 8.00 +``` + +Each writes a separate `parameter_drift_log` row with its own +`trigger_type`. The 8 dn total is preserved from the existing +model; it is now decomposed into citable components. + +### Route cost split — already live, made visible in OTIVM-IV + +``` +COST_VECTURA_RATIO = 0.60 // VECTVRA — freight charge +COST_PORTORIA_RATIO = 0.25 // PORTORIUM — customs duty +// cost_other = 0.15 // horreum, incidentals +PORTORIA_RATE = 0.025 // ad valorem default +``` + +These values are already recorded in `venture_legs`. OTIVM-IV +makes them visible to the player in the FORUM route cards. + +### Labour multipliers — for future goods implementation + +``` +LABOUR_MULTIPLIER_UNSKILLED = 1.00 // 0.50 dn/day +LABOUR_MULTIPLIER_SKILLED_STANDARD = 1.00 // 1.00 dn/day +LABOUR_MULTIPLIER_SPECIALIST_FOOD = 1.20 // garum maker +LABOUR_MULTIPLIER_STONECUTTER = 2.00 +LABOUR_MULTIPLIER_SCULPTOR_DETAIL = 2.50 +``` + +### Transformation routes — new in OTIVM-IV + +The merchant can ship a raw good and receive a transformed good +at destination. Examples: grain → bread, raw clay → vessels, +raw wool → cloth. + +Mechanics: +- Transformation ratio is a LOW confidence placeholder constant + (same pattern as spoilage rates in calibration documents) +- Goods-on-hand are represented as a coin-equivalent delta in + `liquiditas` — no new table, no new parameter +- Transformation is recorded in `parameter_drift_log` with + `trigger_type = 'exchange_complete'` +- The drift log entry records: input good, output good, + ratio applied, coin-equivalent delta, and route label + +This keeps the schema unchanged while making the transformation +economically visible in the sub-trace. + +### Barter — new in OTIVM-IV + +The merchant can exchange goods directly for other goods at an +agreed ratio. No coin moves. The mechanism is identical to +transformation: coin-equivalent delta applied to `liquiditas`, +`exchange_complete` trigger type in drift log. + +### The Market — architectural constraints (deferred) + +The Market will periodically read player databases to derive +supply and demand and set prices. This is the cooperative +simulation layer. Implementation is deferred but the architectural +constraints must not be violated: + +**What the Market can read:** `value_perceived` and parameters +with `observable_level = 'full'` or `'partial'`. + +**What the Market cannot read:** parameters with +`observable_level = 'hidden'`. This is the deception handle — +a merchant can mark a shipment as hidden and it does not appear +in Market aggregation. + +**Ledger fraud:** `value_true ≠ value_perceived` is the second +deception handle. The merchant's ledger shows `value_perceived`. +The Market reads `value_perceived`. `value_true` is the server's +ground truth. A sunk shipment entered as delivered has +`value_perceived = delivered`, `value_true = lost`. + +Both deception patterns are already supported by the schema. +No schema changes are needed when the Market is built. + +### Known calibration flags + +From the cross-good calibration notes: + +1. Current route margins (grain at 67%) are early-game abstraction. + They will need revision when real goods economics are implemented + in full. + +2. Grain private trade margin under annona pressure is approximately + 10.8% — much lower than current game abstraction. + +3. Commission pattern (marble) requires `commission_mode` flag and + distinct route handling — deferred to a future release. + +4. Quality grade multiplier needed for garum and similar goods — + deferred to a future release. + +--- + +## 6. What OTIVM-IV explicitly does not include + +- DWD weather integration — blocked, see Section 1 +- New trade routes or waypoints — blocked on per-H5 pipeline +- The Factor (NPC model) — deferred +- Scenario triggers — deferred +- Ranking or achievements — explicitly deferred in SIMULATOR-vision.md +- H3 hex geometry on the map — deferred pending client-side h3-js +- Real-time dispatch durations (hours not seconds) — deferred +- Market reader implementation — deferred (constraints documented) +- Commission route pattern — deferred +- Quality grade multiplier — deferred +- Any changes to `data/create_player_db.sql` — schema is correct, + do not alter without project owner instruction +- Any changes to `data/create_otivm_db.sql` — world schema unchanged +- Any changes to `server/index.js` TESSERA map endpoint + +--- + +## 7. File inventory — complete and authoritative + +### Files added (new) + +| File | Purpose | +|---|---| +| `src/config/contexts.json` | Dropdown definition — what contexts exist | +| `src/config/context-actor.json` | ACTOR layout, sections, labels | +| `src/config/context-forum.json` | FORUM layout, sections, labels | +| `src/config/context-map.json` | MAP layout | +| `src/components/Shell.jsx` | Sidebar + dropdown + layout grid — built once | +| `src/components/Section.jsx` | Generic panel renderer — built once | +| `src/components/ParameterRow.jsx` | Renders one parameter from actor_parameters | +| `src/components/CostRow.jsx` | Renders one cost line | +| `src/components/DriftEntry.jsx` | Renders one drift log entry | +| `src/screens/Actor.jsx` | ACTOR context — thin, reads context-actor.json | +| `src/screens/Forum.jsx` | FORUM context — thin, reads context-forum.json | + +### Files modified (existing) + +| File | What changes | +|---|---| +| `src/App.jsx` | Shell replaces current tab navigation. Three contexts wired. Expenditure logic added. Background selection state moved to ACTOR context. | +| `src/App.css` | Reduced to project-specific overrides only. Bootstrap handles layout. Roman palette CSS variables retained and extended. | +| `src/constants.js` | Expenditure constants added. Transformation ratio placeholders added. Labour multipliers added. | +| `server/index.js` | Periodic expenditure debit logic added. Three new trigger_type values: `otium_access_fee`, `personal_maintenance`, `officia_obligation`. `exchange_complete` trigger type for transformation and barter. | +| `package.json` | Bootstrap 5.3.3 and Bootstrap Icons 1.11.3 added as pinned dependencies. | + +### Files retired (to be deleted) + +| File | Reason | +|---|---| +| `src/screens/Prologue.jsx` | ACTOR context absorbs both selection UI and read-only summary. One context per function. | +| `src/screens/Ledger.jsx` | Replaced by Forum.jsx. Dispatch logic migrated. | + +### Files not touched + +| File | Reason | +|---|---| +| `src/screens/Map.jsx` | No map changes in OTIVM-IV | +| `src/gameState.js` | Game state shape unchanged | +| `src/api.js` | API calls unchanged | +| `data/create_player_db.sql` | Schema correct, do not alter | +| `data/create_otivm_db.sql` | World schema unchanged | +| `data/repair_player_db_fk.sql` | Repair script, unchanged | +| All `docs/` files | Documentation unchanged except this file | + +--- + +## 8. Implementation sequence + +One file, one step, one confirmation. In this order: + +**Step 1 — Dependencies** +`package.json` — add Bootstrap 5.3.3 and Bootstrap Icons 1.11.3. +Confirm `npm install` and build pass before proceeding. + +**Step 2 — CSS foundation** +`src/App.css` — reduce to project overrides. Bootstrap imported. +Roman palette as CSS custom properties. Build and confirm. + +**Step 3 — Shell components** +`src/components/Shell.jsx` — sidebar, dropdown, layout grid. +`src/components/Section.jsx` — generic panel renderer. +These two files are the foundation. Nothing else is built until +they render correctly with placeholder content. +Two files, one commit. + +**Step 4 — Context configuration** +`src/config/contexts.json` +`src/config/context-actor.json` +`src/config/context-forum.json` +`src/config/context-map.json` +Four files, one commit. No rebuild needed after this step — +JSON only. Confirm files are present in repo before proceeding. + +**Step 5 — Sub-components** +`src/components/ParameterRow.jsx` +`src/components/CostRow.jsx` +`src/components/DriftEntry.jsx` +Three files, one commit. + +**Step 6 — Screen files** +`src/screens/Actor.jsx` +`src/screens/Forum.jsx` +Two files, one commit. + +**Step 7 — App.jsx** +`src/App.jsx` — Shell replaces tab navigation. Three contexts +wired. Expenditure logic added. +One file, one commit. + +**Step 8 — Server** +`server/index.js` — periodic expenditure debit logic. New +trigger types. Exchange_complete for transformation and barter. +One file, one commit. pm2 restart required. + +**Step 9 — Retire old files** +Delete `src/screens/Prologue.jsx` and `src/screens/Ledger.jsx`. +Confirm build passes without them. +One commit. + +**Step 10 — Verify** +Play a full game cycle. Inspect database. Confirm all three +trigger types appear in parameter_drift_log. Confirm ACTOR, +FORUM, and MAP contexts render correctly. Confirm background +selection still works for new players. + +--- + +## 9. Mockup reference + +Two mockup files were produced during design and are available +for reference. They are not committed to the repo — design +artefacts only: + +- `otivm-iv-mockup.html` — first mockup, three-tab layout +- `otivm-iv-architecture-mockup.html` — shell architecture mockup + with dropdown, variable layouts, and embedded ChatGPT brief + +The architecture mockup is the definitive visual reference for +the shell. The CONTEXT_CONFIG object in that file is the direct +source for the four context JSON files in Step 4. + +--- + +## 10. Economic calibration reference + +All cost constants derive from two committed documents: + +``` +docs/economy/cost-calibration-model.md +docs/economy/cost-calibration-additional-goods.md +``` + +Do not invent cost values. Do not change cost values without +updating the calibration documents and noting the source and +confidence level. Every constant in `src/constants.js` that +relates to economics must have a corresponding entry in the +calibration documents. + +--- + +## 11. Market architectural constraints — do not violate + +Even though the Market is deferred, these constraints govern +every implementation decision in OTIVM-IV: + +1. `observable_level` on every `actor_parameters` row is the + Market visibility gate. Set it correctly from the start. + `full` = Market can read. `partial` = Market sees band only. + `hidden` = Market cannot see. + +2. `value_true` is always server ground truth. + `value_perceived` is always what the actor's ledger shows. + Never conflate them. Never store only one. + +3. Every event written to `parameter_drift_log` will eventually + be readable by the Market. Write it as if the Market is + already watching. The trigger_type and delta_note must be + meaningful to an external reader, not just to the game. + +--- + +*OTIVM-IV Roadmap — approved 2026-05-03* +*Calibration documents committed to docs/economy/.* +*Mockups produced and available for reference.* +*Claude chat designs. Claude Code implements. The human decides.*