Files
browser/openspec/changes/bootstrap-game-server-platform-architecture/design.md
T
2026-07-11 14:56:10 +08:00

112 lines
8.1 KiB
Markdown

## Context
The new project starts in `/Users/tasia/Desktop/code/browser` and intentionally splits the system into four subprojects:
- `platform/`: backend control plane for users, game management plugins, server instances, AI providers, jobs, artifacts, logs, and audit.
- `run/`: machine-side executor that performs scoped process, file, log, artifact, and server lifecycle work.
- `platform_web/`: management console frontend for 首页、服务器管理、插件市场、用户管理、AI 提供商管理.
- `plugins/`: game management plugin workspace where each plugin defines how to create and manage one server type and can create many server instances.
The previous implementation mixed API DTOs, models, store code, business logic, frontend types, runtime protocols, plugin execution, and generated rules across many directories. This design treats directory ownership and validation as product requirements, not style preferences.
## Goals / Non-Goals
**Goals:**
- Make the platform a game server management platform, not a SCUM-only application.
- Keep plugin semantics narrow: plugins define server types and server management workflows; they do not own platform transport, AI credentials, or run connections.
- Give AI providers a clear role: model endpoint/key/model configuration used through platform-mediated plugin abilities.
- Split run-platform communication into control, job, log ingest, artifact, and optional game client bridge channels.
- Preserve log continuity when file transfer or plugin file operations are busy.
- Create mandatory directories for DTOs, models, schemas, shared utilities, validators, and frontend types.
- Add a repository structure checker that future changes must update when rules change.
**Non-Goals:**
- No billing, cloud resource sales, or SaaS marketplace features.
- No agent provider or cloud host provider system in this change.
- No direct browser-to-run or plugin-to-run connection.
- No raw UDP log transport for reliable historical logs.
- No implementation of the full backend, frontend, or run binaries in this proposal.
## Decisions
### Decision 1: Four subprojects are hard boundaries
The root project SHALL contain `run/`, `platform/`, `platform_web/`, and `plugins/` only as first-class implementation roots.
Alternative considered: one monorepo package tree with shared internal directories. Rejected because the old project already demonstrated that blurred roots let API structs, database models, protocol structs, and frontend types drift into business logic.
### Decision 2: Plugins are game management plugins
A plugin declares how to create and manage a class of game server. Installing `server.scum` or `server.minecraft` enables users to create multiple server instances from that plugin.
Alternative considered: treating every game-side mod or feature as a platform plugin. Rejected because it fragments one game into many pseudo-platform units and makes server creation unclear.
### Decision 3: AI provider management is a platform service
AI providers store base URL, API key reference, model list, routing mode, timeout, and policy. Plugins call a platform AI invocation API with scoped purpose and inputs; plugins never receive raw keys.
Alternative considered: plugin-owned AI provider configuration. Rejected because credentials would be duplicated, hard to audit, and unsafe for plugin frontends.
### Decision 4: Run communication is channelized by workload
The run executor SHALL use separate logical channels:
- control: hello, heartbeat, capability, capacity, version.
- job: claim, ack, progress, result, cancel, reconcile.
- log ingest: compressed batches, sequence acknowledgement, local spool, retry.
- artifact: chunk upload/download, checksum, resumable transfer, throttling.
- game client bridge: optional game-inside command polling and snapshots when a game needs it.
Alternative considered: one WebSocket with multiplexed message types. Rejected as the primary architecture because large files, long tasks, and high-volume logs can block each other and make backpressure hard to reason about.
### Decision 5: Logs are a data pipeline
Run SHALL collect process output and server log files into a local spool/WAL, upload compressed batches with monotonic sequence IDs, and delete local segments only after platform acknowledgement. Platform SHALL store log metadata separately from log bodies and support pluggable storage backends such as local compressed segments, Loki, ClickHouse, OpenSearch, or Elasticsearch.
Alternative considered: browser-oriented WebSocket logs from run to platform. Rejected because historical query, GPT analysis, retry, and thousands of server streams require durable ingestion semantics.
### Decision 6: File transfer is artifact-based
Plugins and frontend actions SHALL reference `artifactId` or `fileRef`, not host paths or raw run connections. Artifact transfer SHALL be chunked, resumable, checksummed, rate limited, and lower priority than control and log flush.
Alternative considered: synchronous file content inside job results. Accepted only for bounded small metadata or small text reads; rejected for general files because it can block logs and job status.
### Decision 7: Definitions live in fixed directories
Each backend subproject SHALL keep request/response DTOs, database models, domain types, protocol types, validation rules, shared helpers, and API route declarations in dedicated directories. Each frontend or plugin page SHALL keep API clients, page types, route definitions, schemas, bridge types, and shared utilities in dedicated directories.
Alternative considered: colocating structs and helper functions beside handlers for speed. Rejected because the user explicitly wants structure definitions, common functions, database definitions, and API definitions in predictable locations.
### Decision 8: Rules are validated by script
The root `scripts/check-structure.sh` SHALL verify required directories and governance files. Future implementation changes MUST extend the checker when adding new architectural rules.
Alternative considered: relying on AGENTS.md instructions only. Rejected because instructions alone do not prevent drift.
## Risks / Trade-offs
- [Risk] Directory rules may feel heavy before code exists -> Mitigation: start with lightweight presence checks and grow semantic checks with implementation.
- [Risk] HTTP polling jobs can add latency -> Mitigation: begin with pull/long-poll for NAT reliability, then add HTTP/2 or gRPC streaming only where measured latency needs it.
- [Risk] Log storage choice is premature -> Mitigation: define a storage adapter boundary and begin with local compressed segments plus metadata.
- [Risk] Plugin flexibility is reduced -> Mitigation: expose platform abilities through a typed bridge and job/artifact APIs instead of direct run access.
- [Risk] AI analysis may consume too much log context -> Mitigation: require log window extraction, redaction, summarization, and user confirmation before config writes.
## Migration Plan
1. Bootstrap the empty repository with four subproject roots, README files, AGENTS files, OpenSpec proposal artifacts, and the structure checker.
2. Implement minimal platform models and route contracts for game management plugins, server instances, AI providers, run sessions, jobs, artifacts, and log streams.
3. Implement run control, job claim/result, log spool/ingest, and artifact chunk APIs behind interfaces.
4. Implement platform_web pages in the required navigation set and consume only platform APIs.
5. Implement one dev game management plugin as the first proof that a plugin can create multiple server instances and use platform AI/file/log abilities.
Rollback is simple during bootstrap: remove the new change artifacts or directories before implementation starts. After implementation starts, rollback must follow OpenSpec task boundaries.
## Open Questions
- Which backend database will be used first for platform metadata?
- Should log body MVP use local compressed files, ClickHouse, Loki, or OpenSearch first?
- Should the initial run job channel be short polling, long polling, or HTTP/2 streaming?
- What language/runtime should game management plugin action scripts use first?