spec: replace run endpoints with redis registry

This commit is contained in:
npc0-hue
2026-07-30 21:38:11 +08:00
parent 2a17718158
commit 6d71d8d232
6 changed files with 276 additions and 0 deletions
@@ -0,0 +1,42 @@
## MODIFIED Requirements
### Requirement: Server creation requires only plugin type and server name
The system SHALL require only the game plugin type and the server name to create a server instance, and SHALL NOT require a deployment target, run endpoint, or runtime profile at creation time. The creation workflow MAY collect plugin-declared deployment mode, game configuration, and startup fields before submit, but those fields SHALL NOT create a durable run endpoint binding.
#### Scenario: Creation form field set
- **WHEN** an owner opens the server creation workflow
- **THEN** the form requires plugin type and server name only, may present plugin-declared deployment/startup inputs, and presents no deployment target or run endpoint selector as a creation prerequisite
#### Scenario: Creation without any registered runtime session
- **WHEN** an owner creates a server instance while no Run has registered for that instance
- **THEN** creation succeeds and the instance is created without a run endpoint binding
#### Scenario: Runtime session established by run registration
- **WHEN** a generated Run for that instance registers itself with the platform
- **THEN** the platform creates or renews a Redis runtime session lease for that server Run and does not persist a server-to-run-endpoint association
#### Scenario: Runtime profile and endpoint selection are not creation prerequisites
- **WHEN** an owner opens an already-created instance
- **THEN** runtime profile and run endpoint selection are not required to make the instance exist, generate a Run package, or show runtime connection guidance
### Requirement: Build availability is independent of run endpoint capabilities
The system SHALL determine `generate-run` and `generate-client-manager` availability from plugin declarations, runtime bindings, and platform builder readiness, and SHALL NOT require any machine-side Run session or durable run endpoint row to advertise `distribution.build`.
#### Scenario: Instance has only its generated Run runtime session
- **WHEN** a server instance's only live runtime session is its generated Run, which holds no distribution-build authority
- **THEN** `generate-run` remains available and a new run distribution can be generated through the platform builder
#### Scenario: No privileged worker endpoint registered
- **WHEN** no machine-side Run advertises `distribution.build` or no legacy endpoint row exists
- **THEN** run generation still succeeds through the platform Docker builder
#### Scenario: Builder unavailable
- **WHEN** the platform Docker builder is unavailable
- **THEN** the unavailable reason names the platform builder rather than a run endpoint capability
### Requirement: Generated runs hold no distribution-build authority
The system SHALL continue to deny distribution-build work to component-authenticated generated Runs. This restriction is a security boundary and SHALL NOT be relaxed to unblock building.
#### Scenario: Generated run claims a build
- **WHEN** a component-authenticated generated Run session claims work advertising `distribution.build`
- **THEN** the platform does not assign distribution build work to that Run session
@@ -0,0 +1,72 @@
## ADDED Requirements
### Requirement: Redis-backed runtime session registry is required
The system SHALL use Redis as the runtime session registry in development, test, and production environments, and SHALL NOT use an in-memory registry fallback for normal runtime registration, heartbeat, token validation, or job routing.
#### Scenario: Platform starts without Redis
- **WHEN** Platform starts or checks health while Redis is unavailable
- **THEN** runtime registry health is reported unavailable and runtime dispatch operations fail safely without assigning jobs to Runs
#### Scenario: Automated tests exercise Redis registry behavior
- **WHEN** tests cover Run registration, heartbeat expiry, token validation, or job claim routing
- **THEN** those tests use an isolated Redis database or key prefix rather than a memory-only registry
### Requirement: Run registration creates an ephemeral Redis session
The system SHALL authenticate generated Runs with durable component credentials and SHALL store only a short-lived Redis session lease for the live Run connection.
#### Scenario: Valid generated Run registers
- **WHEN** a Run submits a hello request with a valid server instance ID, component kind, component key generation, registration proof, version, target, capabilities, and capacity
- **THEN** Platform authenticates the durable component key and writes a Redis session lease scoped to that server/component identity
#### Scenario: Registration supersedes prior live session
- **WHEN** a second valid Run registers for the same server/component identity
- **THEN** Platform rotates the live Redis session token and the previous session token no longer authorizes heartbeat or job operations
#### Scenario: Invalid token is rejected
- **WHEN** a Run presents an invalid registration proof or stale component key generation
- **THEN** Platform rejects registration and does not create or renew a Redis session lease
### Requirement: Heartbeat leases expire without startup cleanup
The system SHALL represent runtime online state through Redis TTL leases that are renewed by heartbeats and naturally expire without Platform startup cleanup.
#### Scenario: Heartbeat renews lease
- **WHEN** a registered Run heartbeats with the current session token before the Redis TTL expires
- **THEN** Platform renews the Redis lease and updates the safe capability/capacity snapshot
#### Scenario: Run stops heartbeating
- **WHEN** a Run stops heartbeating beyond the configured expiry window
- **THEN** Redis expires the session keys and Platform reports that runtime connection as offline
#### Scenario: Platform restarts
- **WHEN** Platform restarts while Redis still contains live session keys
- **THEN** Platform resumes token validation and routing from Redis without scanning or cleaning stale keys at startup
#### Scenario: Redis loses session data
- **WHEN** Redis restarts or evicts runtime session keys
- **THEN** Platform treats affected Runs as offline until they register again and does not mutate durable server or job records solely because the Redis lease disappeared
### Requirement: Runtime jobs target server components instead of run endpoints
The system SHALL route durable runtime jobs by logical server/component target and SHALL NOT require a durable run endpoint row to create, validate, claim, or complete machine-side runtime work.
#### Scenario: Job is queued for a server Run
- **WHEN** Platform queues lifecycle, config, file, log, or protected-request work for a server Run
- **THEN** the durable job target identifies the server instance and `run` component rather than a run endpoint ID
#### Scenario: Run claims work
- **WHEN** a registered Run claims work with its current session token
- **THEN** Platform derives the server/component target from Redis and assigns only eligible jobs for that target
#### Scenario: Run attempts cross-server claim
- **WHEN** a Run session for one server attempts to claim, acknowledge, report progress, or complete a job targeting another server/component
- **THEN** Platform rejects the operation and preserves the durable job state
### Requirement: Runtime connection projections are safe
The system SHALL expose runtime connection health as a safe projection derived from Redis leases and durable server/component metadata, without exposing session tokens, Redis keys, raw credentials, host paths, or direct sockets.
#### Scenario: Owner views server runtime health
- **WHEN** an authorized owner views a server's runtime connection state
- **THEN** Platform returns safe status, last heartbeat time, version, target OS/architecture, capabilities, capacity, and unavailable reason
#### Scenario: Runtime session secrets remain hidden
- **WHEN** Platform Web, plugin pages, or bridge actions request runtime status
- **THEN** responses exclude session tokens, token hashes, Redis key names, raw component credentials, host paths, and sockets