Otomo — Milestone 1 tech stack overview
Entry point into the milestone 1 doc set. Every decision below is expanded in its own file — this is the index, not a new source of truth.
| Doc |
Covers |
00-common-stack.md |
Shared conventions, Go tooling, network topology, two-service Gateway decision |
01-dashboard.md |
Observability stack, Dashboard service |
02-config.md |
Config service, content publishing |
03-patch-minimal.md |
Patch service, Godot client updater |
04-session-minimal.md |
Session service, friends/parties |
05-gateway-techspec.md |
Gateway implementation spec |
06-auth-identity-contract.md |
JWT/JWKS contract shared by Auth, admin-auth, Gateway |
07-auth-techspec.md |
Auth implementation spec |
Architecture
Godot client Ionic admin UI
│ │
▼ ▼
Gateway Gateway (dev)
player edge, public admin edge, staff only, private
│ │
└──────────┬───────────────┘
▼
Essential services
Go 1.27.1 backend services
│
▼
Data layer
Postgres, Valkey, blob storage
│
▼
Observability
Prometheus, Loki, Alloy
Clients
| Tool |
Role |
| Godot 4.7.2 |
Player client. HTTPRequest + HashingContext for Patch's updater; HTTPRequest + Timer for Session's heartbeat/long-poll loop |
| Ionic 9 + Capacitor 8 |
Staff admin app — one Angular/React/Vue app hosting both the Config and Dashboard modules, not two separate apps |
| nginx |
Serves the built Ionic static bundle — no Node in the runtime container |
Gateway — 05-gateway-techspec.md
| Tool |
Role |
Go, net/http ServeMux |
Routing (method + path pattern matching, stdlib) |
httputil.ReverseProxy |
Proxying to upstream services, with FlushInterval/deadline overrides for SSE and long-poll routes |
golang.org/x/time/rate |
Per-IP rate limiting |
| Deployment |
Two services, two images: gateway (player edge, public) and gateway_dev (admin edge, staff only, private). Separate binaries, not one binary behind a GATEWAY_INSTANCE flag — see 00-common-stack.md §1 |
Identity — 06-auth-identity-contract.md, 07-auth-techspec.md
| Tool |
Role |
crypto/ed25519 (stdlib) |
Key generation and signing, both Auth and admin-auth |
golang-jwt/jwt/v5 |
JWT construction, signing (Auth/admin-auth), and verification (Gateway) |
MicahParks/keyfunc/v3 |
JWKS fetching/caching on the verifying side (Gateway) |
| Two issuers |
Auth issues player tokens, admin-auth (services/admin_auth, Go) issues staff tokens — never cross-trusted, enforced by issuer/audience pinning at Gateway |
Essential services — 01–04, 07
| Tool |
Role |
| Go 1.27.1 |
Pinned exactly across every service |
pgx/v5 + pgxpool |
Postgres driver and connection pool |
goose |
Embedded schema migrations |
prometheus/client_golang |
/metrics instrumentation |
log/slog |
Structured JSON logging |
santhosh-tekuri/jsonschema |
Config's draft/version validation |
valkey-io/valkey-go |
Session's presence and event pub/sub |
| Go 1.27.1 |
admin-auth — the staff identity service (services/admin_auth), same skeleton as every other backend |
Services: Auth, Config, Patch (minimal), Session (minimal), Dashboard, admin-auth.
Data layer
| Tool |
Role |
| PostgreSQL |
One instance, one database per service, no cross-service joins |
| Valkey |
Presence and event pub/sub, Session only |
| Docker volume, SHA-256 content-addressed |
Blob storage for M1 (config JSON, .pck packs). Not MinIO — community edition is unmaintained. Garage/SeaweedFS/RustFS are the candidates if this moves to object storage later |
Observability — 01-dashboard.md
| Tool |
Role |
| Prometheus |
Metrics storage, scraped from every service's /metrics |
| Loki |
Log storage |
| Grafana Alloy |
Log/metric collector — not Promtail, which is end-of-life |
node_exporter, cAdvisor, postgres_exporter |
Host, container, and database metrics |
Build and runtime substrate
| Tool |
Role |
| Docker + Compose |
One bridge network for M1; only the two Gateway services publish ports |
| Local Docker Registry |
Image versioning, enables rollback |
Distroless nonroot images |
Multi-stage builds, minimal runtime surface |
| Jenkins |
Lint (golangci-lint), vuln scan (govulncheck), race-tested tests, build, push, migrate, deploy, readiness poll, auto-rollback |
Explicitly deferred — not part of M1
- Docker Swarm overlay networking (
NET-1) — layered on later without touching service code.
- Matchmaker, Allocator, Gameplay Proxy — next milestone. No routes, no code, no placeholders exist for them anywhere in the current spec set.