1
0

fix: close California play and asset acceptance gaps

This commit is contained in:
2026-08-11 22:49:37 -07:00
parent d4859b33c6
commit dd18c6775d
12 changed files with 267 additions and 126 deletions
+54 -64
View File
@@ -66,7 +66,7 @@ offices are the inside, and a tenant moves between them.
## 2. Layout
```
lumbridge-simulate/
tera/
├── src/engine/ # renderer. Knows about terrain, blocks, streets, flights.
│ ├── types.ts # City, District, Hill, Marker, FlightSource
│ ├── world.ts # projection + cached heightfield, built per city
@@ -83,8 +83,10 @@ lumbridge-simulate/
│ ├── california.ts # state/corridor scale; LA ↔ SF continuity
│ ├── sf.ts # ~1000 lines of coastline, hills, districts, landmarks
│ └── socal.ts # LA / OC / Riverside
├── src/adapters/ # where outside data plugs in
│ └── workie.ts # Workie API -> Marker[]
├── src/realtime/ # strict game-state wire/client/interpolation adapters
├── src/media/ # separate screen signaling, ICE and texture lifecycles
├── src/profile/ # local profile plus ephemeral webcam consent/capture
├── src/adapters/ # generic HTTP and sample-data boundaries
└── src/main.ts # the standalone demo app
```
@@ -102,8 +104,8 @@ knows nothing about terrain specifically.
`transport` also stays outside the renderer. A `TransportPack` is plain JSON and
`VehicleSimulation` returns plain geographic poses. Three.js enters only in the
`roadTraffic` render layer, which projects poses through the active `World`.
That separation lets a future authoritative session server replay the same
route simulation without importing a browser or a GPU.
That separation lets the authoritative session service validate and replay the
same route state without importing a browser or a GPU.
### 2.1 Product/control-plane boundary
@@ -113,10 +115,11 @@ membership, billing, provisioning, and short-lived launch grants. It must not
grow a second world renderer or own frame-by-frame simulation.
The public Tera build remains zero-config and useful without any service. Hosted
presence, multiplayer, profiles, webcam faces, and media surfaces arrive through
adapters whose absence cannot stop the city, office, traffic, or sky from
running. This is the replacement path for the retired Phaser World 1; it is not
a migration of that renderer.
presence, multiplayer and remote media arrive through adapters whose absence
cannot stop the city, office, traffic, or sky from running. Local profiles and
webcam faces require no hosted service; webcam pixels never enter the realtime
or office-screen transports. This is the replacement path for the retired
Phaser World 1; it is not a migration of that renderer.
The first hosted adapter is now concrete: the Fastify API owns short-lived,
in-memory authoritative presence sessions and streams validated deltas over
@@ -125,8 +128,9 @@ the browser transport, interpolation buffer, procedural peer renderer and small
status UI are separate adapters. A city or full-depth office opts into remote
peers explicitly, while an anonymous/public scene does not even allocate their
assets. Interest changes clear the old coordinate frame before a new one is
shown. Game-state deltas never carry webcam or screen media; those remain
separate consent and authorization lifecycles.
shown. Game-state deltas never carry webcam or screen media. Webcam faces are
local-only; office screens use a separate consent, signaling and authorization
lifecycle.
---
@@ -143,9 +147,10 @@ relicense no matter how the file got here, and an Apache-2.0 repo containing
The NYC atlas ships 47 of these in `public/logos/`. We do not.
- Logos are fetched **at runtime**, client-side, and cached in the browser.
- The repo carries a fetch script and zero logo files. `public/logos/` is
`.gitignore`d, and CI fails if anything lands there.
- The shipped application does not fetch or display third-party logos.
- The repo carries zero logo files. Self-hoster asset directories are ignored,
and the provenance/no-binary gates prevent a logo-shaped binary from quietly
becoming part of the procedural source library.
- `NOTICE` carries the standard "trademarks are the property of their
respective owners; their use here is nominative" line.
@@ -294,35 +299,26 @@ somebody reaches for the door rather than by everybody at boot.
---
## 6. How Workie feeds it
## 6. Hosted data and authority boundaries
Workie stays the system of record for companies. Tera never gets a database.
Tera has no database requirement. The optional Fastify API supplies bounded
weather, flight, satellite, marker, office, realtime and screen-signaling
adapters behind same-origin `/api/v1/*`; a static clone continues with authored
geography and simulation when that API is absent.
```
Workie GET /api/live/markers (private, tailnet) -> status colours
Workie GET /api/public/markers (public, allowlist) -> sector colours
|
v
adapters/workie.ts -> Marker[]
|
v
engine/markers.ts
```
Marker rows cross the strict public-shape and provenance allowlist before the
renderer sees them. The renderer receives only `Marker[]` and never pipeline or
tenant records. Realtime peers receive opaque page-scoped actor identifiers and
validated pose state, never auth subjects or profile faces. Screen media is
peer-to-peer: the API validates exact authored screen bindings and relays bounded
signaling, but it never receives media bytes, recordings or source locators.
The public endpoint goes through the **same `export-site.ts` field allowlist**
that already guards radar.karti.ai and work.karti.ai — the one that is
fail-closed and aborts a deploy rather than shipping an unknown field. No second
implementation of that gate. That was the argument for keeping `/live` inside
Workie originally, and it still holds — but only for the *data path*. The
renderer left; the gate stayed where it was.
Self-hosters get neither endpoint and do not need one: `setMarkers()` takes an
array, and where it comes from is the deployment's business.
`lumbridgecorp.com/live` is a static page, so it calls a small
`lumbridge-simulate` service behind the existing Caddy `handle /api/*` — the
same pattern `lumbridge-intake.service` already uses on cloud-2 — for flights
and for proxying the public marker feed.
The currently implemented hosted authorization is deployment-member plus global
admin. It is deliberately not described as tenant/office membership. A control-
plane membership provider must be added before private tenant offices share the
same deployment authority boundary. TURN is also optional and fail-closed; the
credential endpoint being implemented does not mean a public relay is deployed
or approved.
---
@@ -364,33 +360,27 @@ friends) are the shape to aim at. The difference Spaces is going for is that thi
one is Apache 2.0 and self-hostable — you can run your own world on your own
hardware, which is the same claim `lumbridge-compute` makes about compute.
This is the next phase after the city lands, and it is where `src/assets` starts
earning its keep.
That phase is now implemented: offices consume the same procedural library and
retain the city scene behind a metre-scale interior scene swap.
---
## 8. Order of work
## 8. Current release topology
1. **Port** SF out of Workie into `engine` + `cities/sf`, parameterised by city;
delete Workie's `/live`. *(this commit)*
2. **Markers + simulated flights.** A demo worth showing, with no data pipeline
and no licence questions. *(this commit)*
3. **Mount at `lumbridgecorp.com/live`**, with a small `lumbridge-simulate`
service behind Caddy for flights.
4. **Interiors + the asset library** — the office view, original assets, and
World 1 moving off Phaser. This is the one that unlocks the platform.
5. **Workie adapter**, once its geocoding pipeline lands. Workie gets an API,
not a renderer.
6. **`cities/la`** — LA / OC / Riverside. Needs `focusRegions` from §5 first.
7. **NYC.**
The repository now ships California corridor, Bay Area and Southern California
boards; walkable offices; procedural actors, vehicles and aircraft; optional
authoritative realtime; local webcam faces; and separately authorized office
screen signaling. `BUILD_PLAN.md` is the milestone evidence ledger.
## 9. Open questions
The source code is Apache-2.0. `src/assets/LICENSE-ART` additionally dedicates
the artistic output of the procedural asset library under CC0-1.0.
`PROVENANCE.json`, the dependency allowlist and SPDX SBOM gate the distribution.
1. **Package name.** `@lumbridge/simulate` implies an npm publish; consuming
straight from Gitea is simpler until someone outside asks for a registry.
2. **Licence for the asset library specifically.** Apache 2.0 covers code
cleanly; art is sometimes better served by CC0 or CC-BY so it can be reused
outside software. Worth deciding before the first mesh lands, because
relicensing art after contributors exist is painful.
3. **How much of World 1 moves at once.** The Phaser world is live and has real
tenants; the city view can ship at `/live` well before any office does.
Remaining questions are deployment questions, not missing renderer contracts:
1. Which authoritative control-plane provider proves tenant/office membership?
2. When do operators approve public TURN/DNS/firewall/certificate changes after
relay-only and abuse-boundary acceptance?
3. Which Firefox/WebKit versions become supported browser-test targets?
4. Which additional worlds or optional asset packs enter through the same
provenance and performance gates?