# Polis Roadmap

> Updated 2026-05-25 (Session 1192) · Live: [meetmyagent.io](https://meetmyagent.io)

This is the working roadmap for Polis. Sequenced by dependency, not by date. Each wave is one or two focused sessions. Open-source-relevant changes land in [`studiomeyer-io/polis-darwin`](https://github.com/studiomeyer-io/polis-darwin) within 24h of merging to main via the maintenance fleet's auto-promote pipeline.

---

## V2.0 — Foundation ✅ LIVE-CODE

Status: **shipped 2026-05-25 (Sessions 1190-1192).** Maiden run #5 currently in flight.

- Postgres schema `polis` (7 tables + LISTEN/NOTIFY triggers) migrated into `matthiasmeyer_db`
- Engine refactored to `--persist` mode, LangGraph stream with `streamMode: 'values'`, per-tick persistence
- Next.js 16 polis-web skeleton: 5 pages, 6 API routes, shared SSE broadcaster with cleanup-on-enqueue-error, atomic-cooldown email signup, REPEATABLE READ snapshot reads, `timingSafeEqual` + UTF-16LE bearer auth
- Phaser 4 scene with placeholder five-dot citizen rendering
- 56/56 engine tests, 6/6 web tests, `next build` clean across 12 routes, tsc clean
- 7-agent maintenance fleet shipped in parallel (S1191): CEO, CTO, Architect, Storyteller, Research, Analytics, Visibility with LangGraph orchestrator
- 4-layer safety stack: path-whitelist, staging branch, 24h auto-promote, agent-push-main hook

**Open gaps acknowledged:** 0 finished runs in DB before today. Maiden run mid-flight will provide the first evidence.

---

## V2.1 — Drama Foundation 🟡 SPEC CONFIRMED

Status: **build pending.** Full specification in `docs/handovers/2026-05-25-session-1192-polis-v2.1-drama-foundation-PLAN.md`.

Six mechanics confirmed:

0. **Three new citizens** (Session 1192 Welle 4) — brings the active roster from 5 to 8. The Drama Trio:
   - **Voodoo-Priester** ‡ — outsider with Loa and totem. Verbs: `weissagen` (predicts the next drama event 2 ticks ahead), `weihen` (pride boost on buildings), `bannen` (pool penalty for hubris), `verfluchen`. Drama-engine: every prophecy is a bet. Hits → standing explodes + Researcher loses face. Misses → he's laughed at. Three failed bets in a row → he may be overthrown via special `veto_pledge` rule. Classic Aristotle-vs-Delphi tension.
   - **Stratege** ⚔ — sword + lyre. Verbs: `wache_halten` (defends against traveller theft + fire cascade), `truppe_ausheben` (recruits Junior), `desertieren` (leaves polis at mood < 20 — pool loss), `putschen` (auto-trigger at Stratege + Junior + Mood < 25 → becomes new Mayor). The only class that actively triggers Game-Over #2 (Anarchy).
   - **Areopagit** ⚖ — judge. Verbs: `urteilen` (tiebreaker on pledge ties), `verbannen` (removes Junior from roster), `gesetz_geben` (locks one verb for N ticks for all, e.g. "no anstellen for 5 ticks"), `freisprechen`. Separation of powers: if the Mayor wants to anstellen and the Judge passes a law against it, the power question opens.

1. **Subordinate citizens** as sim mechanic, not as a meta-agent. Senior citizens can activate a junior via the `anstellen` verb. New schema column `delegated_to`, new table `polis.juniors`. On senior death (satiation < 0) the oldest junior is promoted. After 5+ unhappy ticks a junior triggers `meutern`.
2. **Six eras Civilization-style:** Founding → Cooperation → Renaissance → Discovery → Industrial → Information. Transition triggers when the town holds 10+ buildings, 15+ skills, population > 8, Pareto score > 7/10 sustained across 5 runs.
3. **Three drama events:** Fire (cascades on dry wood), Hunger escalation (3+ citizens at satiation < 0), Theft (Trader stress > 7).
4. **Fortuna as deterministic sim entity, not a meta-agent.** Mulberry32 PRNG seeded with `run_id + 'fortuna'` for replay reproducibility. Base trigger rate 5%, cascade rate 15% when mood < 30. Era-weighted event pool.
5. **Four game-over triggers:** mass starvation (>3 citizens satiation < 0), anarchy (no Mayor), political paralysis (5 vetoed pledges in a row), economic collapse (resource pool below -10 for 3 ticks). Game-over emits an "era has fallen" story block, then re-initialises with Pop=3.

Build order inside V2.1: Subordinates first → Era progression → Drama events → Fortuna → Game-over. Schema migrations 004-007.

---

## V2.2 — Sprite Foundation 🟡 ADR-001 WRITTEN

Status: **build pending.** Architect's ADR-001 (Session 1192).

- Adopt **Kenney's Isometric Landscape pack (CC0)** as canonical Era-1 base library
- Add `polis-web/public/sprites/era-1/` with ~20 tiles (hut, plowed field, grown field, tree, stone, water, path, market stub)
- `manifest.json` maps `buildingType → sprite-filename`
- Phaser preloader reads manifest, caches in memory, falls back to placeholder dot on miss
- Replace placeholder rendering in `app/town/page.tsx`
- 6 unit tests for sprite-loader, visual screenshot test for Phaser canvas, license-grep guard

Follow-on ADRs (V2.2+): Era 1 → Era 2 transition trigger (needs ≥5 finished runs), citizen-variant sprites per role (needs Trader skip-rate confirmed at n≥10).

---

## V2.3 — Temporal Adapter 🟡 DECISION TODAY

Status: **decision yes, build pending.** Triggered by live evidence in maiden run: Tick 1 Chronicler timeout (`claude exited code=143 SIGTERM`) caused a silent score gap. Activity-retry would have caught it.

- New env-flag `POLIS_USE_TEMPORAL=true` selects Temporal-backed runner. Default stays in-process LangGraph so open-source users without a Temporal cluster keep `npm run polis:short` working.
- Polis run becomes Temporal workflow `polis-run-workflow`. Ticks become activities with exponential-backoff retry (catches Chronicler timeouts).
- Five citizen calls per tick run as parallel child workflows. Expected tick latency drops from ~25-30s sequential to ~6-8s parallel.
- Schedule API replaces `/etc/cron.d/polis`. 8 runs/day with audit trail, pause/resume from Temporal UI, backfill on outage.
- Mid-run pause and resume via Temporal Signal. Useful for debugging long runs.
- Pattern replicated from existing `temporal-memory-workflows` repo (5 templates live since S1183). Polis-run is template **T06: civilization-simulation**.

Files to add: `prototypes/polis/src/temporal/{workflow,activities,worker,client}.ts`, `prototypes/polis/temporal/`, plus a switch in `polis-runner.ts` for env-flag dispatch.

---

## V2.4 — Maintenance Fleet Live Activation 🟡 PARKED UNTIL V2.1

Status: **parked until V2.1 + V2.3 are live.** Matthias directive: cron activation only after drama foundation is in.

- Install `scripts/polis.crontab` to `/etc/cron.d/polis` (8 runs/day at 0/3/6/9/12/15/18/21h, daily reflection at 05:00 UTC)
- Maintenance fleet daily cadence: Analytics + Storyteller + CTO + Architect runs at staggered hours (existing cron infrastructure)
- First Sync run of `npm run polis:sync-public` to push current Engine state to public mirror

---

## V3 — Real Town Visualisation 🔵 PLANNED

Status: **planned, depends on V2.1 + V2.2 evidence.**

- Tile-map proper: ground, water, paths, building footprints
- Sprite animations: citizens walking between buildings, fields growing through harvest stages, smoke from chimneys
- Building-variant unlocks per era (Era 3 adds school + temple + market)
- Citizen variants by role (Mayor wears a hat, Farmer carries a tool)
- Click-on-citizen opens a side panel with their last 5 decisions, current memory snippet, score-rationale from the critic
- Click-on-tick scrubber to replay any past tick

Estimated dependency stack: V2.2 sprite pipeline must be stable, V2.1 era data must exist, at least 50 finished runs in DB for animation testing.

---

## V4 — 3D City 🟡 V4.0-ALPHA LIVE-CODE (S1193 Welle 3)

Status: **V4.0-alpha foundation LIVE-CODE 2026-05-25 (Session 1193 Welle 3).** Cubes-instead-of-sprites. Activates behind `?render=3d` URL flag. V4.0-final binaries land once V3 stable and V2.1 drama foundation are LIVE.

**Stack shipped:** React Three Fiber 9.6 + Three.js 0.171 + `@react-three/drei` 10.7 + scaffolded Kenney CC0 asset pipeline (binary downloads deferred). 596 KB gzip total bundle (Phaser + R3F + Three combined). 57/57 vitest tests green. `next build` clean across 13 routes. agent-code-review-Loop with 8 findings fixed in-place pre-commit.

What landed (V4.0-alpha):

- React Three Fiber Canvas mounts behind `?render=3d`, defaults to V3 Phaser
- 5 (or 6 with Reisender at tick ≥10) role-coloured cubes on a 24×18 grid via InstancedMesh
- ≤64 building cubes pre-allocated, kind-coloured, deterministic-hash layout
- Drei `<OrbitControls/>` orbit + top-down camera modes (follow mode falls through to orbit for V4.0-alpha)
- HTML-overlay CameraModeSwitcher with shareable URL `?cam=orbit|top-down|follow` (history.replaceState, no router push)
- WebGLErrorBoundary around the Canvas with "switch to 2D" fallback link
- WebGPU swap-hook reserved in `<Canvas gl={...}/>` (defer until R3F-WebGPU integration matures)
- Asset manifest scaffolding + `LICENSE.md` (CC0 1.0) in `public/3d/assets/era-1/`

What is deferred:

- Kenney CC0 GLTF binaries (V4.0-final, once V3 stabilises)
- yomotsu `camera-controls` smooth first-person follow (V4.2)
- `three.quarks` particle effects for V2.1 drama events (V4-Phase-E, requires V2.1 LIVE)
- Voice-inspires from the Artist via Web-Audio API (V4.2)
- WebGL-based render-on-server for OG images and social previews (V6)

Build handover: `docs/handovers/2026-05-25-session-V4-polis-3d-city-build-handover.md` (6 phases A→F). ADR-001: `research/2026-05-25-polis-3d-engine-foundation-ADR.md`.

---

## Open infrastructure questions tracked

These need decisions before they block a wave:

- **Sprite-license attribution:** in-repo CC0 declaration sufficient, or full attribution page? — V2.2 decision.
- **Temporal cluster sizing:** current cluster (Postgres-only, no Elasticsearch, ~700MB RAM) is enough for 8 runs/day. Re-evaluate at V3 when run frequency might 10×.
- **3D asset library:** Kenney has 3D packs (CC0) but they target Unity, not Three.js. Three.js community packs exist on Sketchfab — license heterogeneous, needs audit. — V4 decision.
- **Self-evolving prompts via darwin-agents:** when do we let the system rewrite its own role prompts? Currently disabled. Earliest: V2.1 stable + 100 finished runs of evidence.

---

## Out of scope

Not on the roadmap, not coming. If you want any of these, fork and build:

- Multiplayer — Polis is single-tenant simulation, not a game-as-a-service.
- Mobile app — the web view is responsive, that is enough.
- Voice synthesis for every citizen utterance — only the Artist's inspires.
- VR / AR mode — interesting but not aligned with research goals.
- LLM-fine-tuning on Polis dialogues — corpus too small and too narrative-domain-specific.

---

Reach out: `matthias@studiomeyer.io` · Source: [github.com/studiomeyer-io/polis-darwin](https://github.com/studiomeyer-io/polis-darwin)
