feat: 完整游戏运维功能

This commit is contained in:
npc0-hue
2026-07-18 09:04:01 +08:00
parent f3b14b7945
commit 48b8ad8d6c
187 changed files with 16607 additions and 1140 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-17
@@ -0,0 +1,107 @@
## Context
The existing distribution workflow validates a plugin-declared client-manager profile, queues a real `distribution.build` job, injects a separate component key through authenticated build input, and publishes an available artifact only after chunked upload succeeds. It does not represent an installed instance, deploy the artifact through Run, supervise the companion process, authenticate the component as its own actor, reconcile health after Platform or Run restarts, or provide update/rollback/uninstall workflows.
The implementation spans the plugin contract, Platform persistence and APIs, the independent Run repository, and platform_web. Existing boundaries remain mandatory: Run is not reintroduced into this repository; browser/plugin callers never receive raw secrets, paths, PIDs, sockets, or endpoint addresses; job, artifact, log, control, and optional game-client traffic remain isolated; and existing dirty changes in both repositories must be preserved.
## Goals / Non-Goals
**Goals:**
- Carry a plugin-declared client manager from a real build artifact through authorized deployment, installation, registration, health, control, update/rollback, revocation, and safe uninstall.
- Persist a durable Platform aggregate and a Run-local journal so retries, cancellation, stale attempts, lease expiry, and restarts converge instead of reporting synthetic success.
- Authenticate Client Manager directly as a separate component identity with a short-lived session and heartbeat contract, while retaining the distinct singleton component key and generation already used at build time.
- Restrict Run execution to typed deployment and lifecycle operations inside a controlled workspace with checksummed artifacts and declarative executable/health metadata.
- Project safe, useful lifecycle state, real job progress, recovery actions, and audited confirmations into the existing game-operations console.
**Non-Goals:**
- Billing, cloud host sales, provider marketplaces, host provisioning, or a general remote administration surface.
- Arbitrary shell commands, plugin-selected host paths, direct browser/plugin access to Run or Client Manager sockets, or reuse of Run sessions/leases/keys for Client Manager.
- Production KMS, public code-signing trust, private-source credential management, or fleet-wide rollout orchestration. Existing envelope encryption and checksum verification remain the bounded first-party mechanisms.
- Claiming production readiness for client-manager fleets, production sandboxing, or later operations-console work.
## Decisions
### Decision 1: A durable installation aggregate owns lifecycle state
Platform adds one `ClientManagerInstallation` per server instance and profile. It references, but is not the same record as, a `ClientManagerDistribution`. The aggregate stores the assigned Run endpoint, target tuple, desired/active/previous artifact and version metadata, current component-key generation, deployment generation, lifecycle status and phase, current job, last successful job, health summary, last seen, retryable failure, and timestamps. Distribution states remain `building`, `available`, `failed`, or `revoked`; installation states cover `requested`, `building`, `available`, `deploying`, `installed`, `registering`, `online`, `degraded`, `offline`, `updating`, `rolling_back`, `stopping`, `uninstalled`, and `failed`.
All transitions are validated in the service layer and persisted before dispatch. Terminal job projection and component heartbeat advance the aggregate idempotently. A startup/periodic reconciler rebuilds missing projections from durable jobs/sessions and moves timed-out health to `degraded` then `offline` without deleting history.
Alternative: derive lifecycle state from the latest build job and heartbeat. Rejected because it loses desired state, previous deployment, retries, uninstall history, and restart reconciliation.
### Decision 2: Run executes typed lifecycle jobs with strict fencing
Platform uses dedicated job kinds for `client-manager.deploy`, `client-manager.control`, `client-manager.update`, `client-manager.rollback`, and `client-manager.uninstall`. Payloads name logical installation/profile/artifact IDs, target tuple, version/revision, component-key generation, deployment generation, action, checksum, and idempotency key only. Platform accepts them only when user/server/plugin/endpoint authorization, profile capability, endpoint capability, artifact ownership, target/revision compatibility, current key generation, and allowed state transition all agree.
Run validates the same immutable fields, leases jobs through the existing durable scheduler, and records attempt plus fencing generations in a local journal. Duplicate idempotency keys return the recorded outcome; a stale attempt or deployment generation cannot replace a newer active deployment. Cancellation is checked between artifact chunks and activation steps. Retriable failures retain staging state; permanent validation failures never execute.
Alternative: model lifecycle as generic commands or reuse game-server lifecycle jobs. Rejected because arbitrary commands are unsafe and client-manager identity/deployment semantics differ from both Run and the managed game server.
### Decision 3: Deployment uses controlled slots and atomic activation
Run owns a configured client-manager workspace below its data root. Each installation receives stable internal `active`, `previous`, and `staging/<deployment-generation>` slots. Artifact bytes are downloaded on the artifact channel with offset/checksum resume metadata, extracted with traversal/link checks, and verified against the Platform checksum before activation. The executable/config paths are resolved from the approved profile/package contract, never from the API caller. Activation uses an atomic rename where supported; the previous slot is kept for one bounded rollback generation.
Uninstall stops the supervised process, revokes/forgets the local component session material, and removes only the installation's controlled slots and journal entry. It never follows symlinks or deletes server/shared roots. History and audits remain in Platform.
Alternative: unpack directly over the active files. Rejected because cancellation, partial download, checksum failure, and rollback would leave an indeterminate executable.
### Decision 4: Client Manager has a separate signed identity and session
The generated package retains the current client-manager component key and generation. Initial registration signs a canonical request with that key, timestamp, and nonce. Platform resolves the same-server/component key, verifies generation and ownership, rejects expired timestamps or replayed nonces, and checks installed artifact version/revision/capabilities against the active deployment. Successful registration creates a randomly generated short-lived Client Manager session, persists only its hash and metadata, and returns the bearer token only to the Client Manager process.
Heartbeat and capability reports use that component session, not the Run control session or Run job lease. Sessions are bound to installation ID, server ID, profile, key generation, deployment generation, and active artifact. Reset, explicit revoke, update activation, rollback, uninstall, ownership/endpoint reassignment, or expiry revokes the session. A new deployment must register again. Platform stores bounded replay nonces and prunes them after the signature window.
Alternative: let Run proxy its own Platform session for the child process. Rejected because it would let a client-manager compromise inherit Run's broader machine authority and would couple component health to Run control traffic.
### Decision 5: Supervision and health are declarative and bounded
Profiles declare a fixed executable relative path, fixed argument keys/placeholders, startup timeout, stop timeout, health mode, health interval/timeout, required capability names, and whether start/restart/update/rollback are allowed. Validation rejects shell metacharacters, absolute/traversing paths, environment secrets, raw sockets, and unknown capabilities. Run launches only the approved relative executable from the active slot, captures bounded diagnostics, and reports logical process/health states without PIDs or paths.
Health can be process-presence or a bounded component self-report contract. Platform uses signed component heartbeats as the authoritative online signal, with Run process state as deployment/control evidence. Missing heartbeats transition online to degraded and then offline according to profile bounds.
Alternative: accept plugin-provided shell start/health commands. Rejected because it creates an unrestricted execution and data-exfiltration path.
### Decision 6: Updates are single-installation staged transactions
An update requires an available current-generation artifact with the same server/profile/target, a compatible declared version/revision, explicit operator approval, and a healthy installed baseline unless force recovery is explicitly allowed. Run downloads and verifies the new artifact in a staging slot, stops the old process only at activation, swaps slots, starts the candidate, and waits for bounded process/component health. Success commits the active/previous references; failure automatically restores the previous slot and reports `rolling_back` followed by the real result.
Platform rejects revoked artifacts, stale key/deployment generations, cross-target or cross-owner artifacts, and replayed update requests. Restart reconciliation resumes from the durable phase or safely rolls back; it never marks a later phase complete based on a timer.
Alternative: overwrite and restart immediately. Rejected because it cannot prove health or recover from a broken package.
### Decision 7: API and UI expose a safe action projection
Platform provides installation summary/detail, deploy, control, update, rollback, session revoke, retry, and uninstall APIs plus component-only register/heartbeat endpoints. Operator endpoints require the existing session/role/server authorization; component endpoints use the separate signature/session authenticator. Action availability is computed from installed plugin declarations, runtime binding completeness, server ownership, endpoint online/capabilities, distribution state/ownership/target/key generation, installation state, and current user permission.
platform_web renders a Client Manager operations section on Server Detail and compact availability in server actions. It shows profile, target, desired/active/previous versions, artifact and job IDs, deployment generation, safe health/last-seen reason, build/deploy/register/control/update/rollback/uninstall phases, retry guidance, and destructive confirmations. It never renders a raw key, token, secret ref/value, path, PID, socket, credential, endpoint address, DSN, or RCON password.
### Decision 8: Auditing and channel isolation are first-class invariants
Every build/deploy/register/start/stop/restart/update/rollback/revoke/uninstall success, failure, and denial records a durable audit with actor type, safe actor ID, server, profile/component, installation/job/artifact IDs, result, and redacted reason. Component heartbeats are summarized as health state rather than producing an unbounded audit event per pulse.
Artifact download remains resumable and lower priority; Run control heartbeat, job ack/result/cancel, log spool upload, and optional client-manager traffic use independent workers/queues. Channel-isolation tests exercise a stalled client-manager download and prove the other channels progress.
## Risks / Trade-offs
- [Risk] A malicious or compromised source repository can still produce a hostile binary. → Continue requiring approved HTTPS repositories, pinned revisions, fixed build adapters, isolated build workspaces, bounded logs, and explicit operator deployment; do not claim public untrusted builds are production safe.
- [Risk] Atomic rename and executable replacement differ across operating systems. → Keep platform-neutral slot semantics, isolate OS-specific activation in Run, retain the prior slot, and fail without changing active state when atomic activation is unavailable.
- [Risk] Platform and Run can observe different phases during network loss. → Persist intent before dispatch, use idempotency/deployment generations, reconcile job/session/journal state, and favor safe `degraded`/`failed` projections over inferred success.
- [Risk] Key reset immediately invalidates an online component. → Revoke sessions and old distributions, mark the installation as requiring a current-generation rebuild/redeploy, explain recovery in UI, and never silently rotate a package secret.
- [Risk] Heartbeat writes and nonces can grow storage. → Store bounded summaries, unique nonce digests within a short verification window, and prune expired sessions/nonces during reconciliation.
- [Risk] Safe extraction and cleanup are security-sensitive. → Reject traversal, links, device files, unexpected package layouts, and any deletion outside the configured client-manager workspace; cover these cases with tests.
## Migration Plan
1. Extend and validate plugin profile declarations without changing existing installed profile records; profiles lacking the new deployment contract remain build/download-only and lifecycle actions are unavailable with a safe reason.
2. Add Platform models/repositories and initialize installation/session/nonce state without mutating existing distributions or component keys.
3. Add typed Platform APIs/jobs/reconciliation and independent component authentication behind capability gating.
4. Add Run protocol/runtime support, controlled workspace/journal, supervisor, update/rollback, and uninstall safety.
5. Enable the full profile for the first-party SCUM example and add platform_web lifecycle management only when the API projection advertises actions.
6. Verify both repositories and all consumers. Rollback hides new actions and stops dispatching lifecycle jobs; existing distribution download remains available and durable lifecycle/audit history is retained.
## Open Questions
- Production code-signing, KMS-backed component keys, private repository credentials, multi-node fleet rollout, and long-term deployment artifact retention remain explicit follow-up work.
- The first implementation supports one active installation per server/profile and one retained previous slot; multi-instance client-manager replicas require a later contract.
@@ -0,0 +1,32 @@
## Why
Client-manager support currently ends after a real package is built and downloaded: Platform does not durably deploy, register, supervise, update, roll back, revoke, or uninstall the companion process. Operators therefore cannot complete a secure build-to-online-to-retired lifecycle or distinguish real machine state from package availability.
## What Changes
- Extend plugin client-manager profiles with version/revision, deployment mode, required capabilities, health contract, lifecycle actions, compatibility constraints, and update policy while continuing to reject arbitrary commands and secret-bearing declarations.
- Add a durable Platform client-manager installation aggregate and state machine covering request, build, availability, deployment, installation, registration, online health, degradation/offline detection, update/rollback, stop, failure, revocation, and uninstall history.
- Add typed `client-manager.deploy`, lifecycle control, update, rollback, and uninstall jobs that only an authorized, online, capable Run endpoint may execute for a same-server, same-component, target-compatible, current-generation available artifact.
- Add a client-manager component identity, signed registration/session/heartbeat protocol, capability fencing, expiry/replay protection, and revocation that is separate from Run control registration, jobs, leases, and credentials.
- Add Run-side staged/resumable artifact deployment, checksum verification, atomic activation, bounded process supervision, durable local journals, reconciliation, retry/cancel/idempotency fences, health checks, update rollback, and safe uninstall of controlled workspaces only.
- Add server-list/detail Client Manager management workflows for version/build/deployment/registration/health, start/stop/restart, update/rollback, key reset recovery, failure retry, revoke, and uninstall, backed by real job progress and confirmation flows.
- Add durable audit and safe status projections for every sensitive operation while preventing plugins and platform_web from receiving raw keys, sessions, secret refs/values, host paths, PIDs, sockets, credentials, or direct Run endpoint details.
- Preserve independent control, job, log, artifact, and optional client-manager bridge channels so client downloads and traffic cannot block Run heartbeat, job results, or log upload.
## Capabilities
### New Capabilities
- `secure-client-manager-lifecycle`: Secure deployment, component identity, durable state, health, bounded control, update/rollback, revocation, uninstall, reconciliation, auditing, and operator workflows for plugin-declared client managers.
### Modified Capabilities
- `run-distribution-and-client-managers`: Client-manager build artifacts become inputs to a real deployment lifecycle, and key reset/revocation must fence installed instances and require a current-generation redeploy.
## Impact
- `plugins/`: manifest schema, SDK/bridge contracts, SCUM and Minecraft examples, unsafe fixtures, validation, and documentation.
- `platform/`: domain/model/repository state, validators, signed component-session protocol, job orchestration, reconciliation, audit, DTOs, API routes, authorization, and documentation.
- Independent `run/` repository: protocol contracts, artifact deployment, local journal/workspace safety, process supervision, health reporting, lifecycle execution, update/rollback, and channel-isolation tests.
- `platform_web/`: API types/schemas/client, Server Detail Client Manager workspace, server action availability, status/progress/confirmation/error states, tests, and browser acceptance.
- No billing, cloud-host/provider marketplace, arbitrary shell, general remote control, production KMS/code-signing, or fleet-orchestration claim is introduced.
@@ -0,0 +1,35 @@
## MODIFIED Requirements
### Requirement: Run and client-manager keys are isolated singletons
Run executors and plugin-declared client managers SHALL use different authentication secrets, and each server/component SHALL have exactly one current active key stored encrypted in the platform database. A deployed Client Manager SHALL exchange proof of its current component key for a separate short-lived component session and SHALL never use a Run control session or job lease.
#### Scenario: Client manager is generated after run
- **WHEN** a plugin-declared client-manager package is generated for a server that already has a run package
- **THEN** platform MUST create or reuse the server's current encrypted client-manager key and MUST NOT reuse, reveal through API metadata, or derive it from the run key
#### Scenario: Component key reset is requested
- **WHEN** an operator resets a server's run key or client-manager key
- **THEN** platform MUST replace the encrypted database key for that component, increment the key generation, revoke all packages generated with prior generations, revoke matching component sessions and installed deployment fences, mark the affected installation as requiring current-generation rebuild and redeploy, and record an audit event identifying the component kind without logging raw key material
#### Scenario: Old package authenticates after reset
- **WHEN** a run or client-manager package generated before the latest key reset attempts to authenticate, register, heartbeat, deploy, or execute lifecycle work
- **THEN** platform MUST reject the old key, session, artifact, or generation and require the operator to regenerate and redeploy the corresponding run or client-manager package
### Requirement: Client-manager packages are plugin-declared builds
The platform SHALL support plugin-declared client-manager build profiles for companion executables that require source checkout, configuration injection, and compilation before download or secure lifecycle deployment. Only a real available build artifact with a current component-key generation SHALL be eligible for deployment.
#### Scenario: SCUM-style client manager is generated
- **WHEN** a plugin declares a client-manager build profile with repository, revision policy, supported target platform, build system, config template, output artifact paths, deployment contract, lifecycle capabilities, health contract, compatibility constraints, and update policy
- **THEN** platform MUST create a run-worker build job that checks out the approved source and revision, injects configuration obtained through the authenticated job-input channel, compiles the target executable, uploads the downloadable artifact through the artifact channel, records deployable version/target/key-generation metadata, and redacts secrets and workspace paths from progress and build results
#### Scenario: Client-manager build is still running
- **WHEN** the source checkout, environment check, dependency download, compile, artifact upload, or publication stage is incomplete
- **THEN** platform_web MUST display the corresponding real job progress and MUST NOT mark later build or deployment stages complete on a local timer
#### Scenario: Unsupported client-manager target is requested
- **WHEN** an operator requests a client-manager build for an OS/architecture not declared by the plugin profile
- **THEN** platform MUST reject the request before cloning source or creating a credential
#### Scenario: Built artifact is selected for deployment
- **WHEN** an operator selects a client-manager distribution for lifecycle deployment
- **THEN** platform MUST require status available, current key generation, matching server/profile/component/target, approved revision and compatibility metadata, authorized server access, complete runtime binding, and an online assigned Run endpoint with the declared deployment capabilities before creating a typed deploy job
@@ -0,0 +1,153 @@
## ADDED Requirements
### Requirement: Plugins declare bounded client-manager lifecycle contracts
Game plugins SHALL declare client-manager version/revision metadata, supported targets, deployment mode, required Run and component capabilities, relative executable contract, bounded lifecycle actions, health contract, compatibility constraints, and update policy before Platform enables lifecycle operations.
#### Scenario: Valid lifecycle profile is installed
- **WHEN** a plugin declares a client-manager profile with a supported target, pinned or policy-approved revision, fixed build adapter, safe relative executable, bounded start/stop/restart and health settings, and known capability names
- **THEN** plugin and Platform validation MUST preserve the declaration and Platform MUST derive lifecycle availability from the installed declaration, runtime binding, server ownership, and assigned endpoint capabilities
#### Scenario: Unsafe lifecycle profile is submitted
- **WHEN** a plugin declaration contains arbitrary shell, an absolute or traversing path, raw credentials, secret or token values, direct sockets, host endpoints, environment secrets, unknown capabilities, or an unbounded health/control action
- **THEN** plugin and Platform validation MUST reject it before registration or lifecycle dispatch
### Requirement: Platform gates every lifecycle action against current ownership and capability state
Platform SHALL authorize client-manager build, deploy, register, control, update, rollback, revoke, retry, and uninstall independently using the current actor, server visibility, installed plugin declaration, runtime binding, assigned Run endpoint, artifact ownership, target, revision, component key generation, and lifecycle state.
#### Scenario: Authorized owner deploys an available build
- **WHEN** a server owner or authorized administrator selects an available current-generation distribution for the same server, profile, target, and approved revision while the assigned Run endpoint is online and declares client-manager deployment capability
- **THEN** Platform MUST create or reuse one typed deployment intent and job and MUST expose its real state and progress
#### Scenario: Mismatched lifecycle input is requested
- **WHEN** an actor supplies another owner's server, another server or component artifact, another Run endpoint, a mismatched target or revision, an expired or revoked distribution, or a stale component-key generation
- **THEN** Platform MUST deny the operation before job creation, MUST record a redacted denial audit, and MUST NOT reveal whether an inaccessible resource exists
#### Scenario: Service or component credential calls an operator endpoint
- **WHEN** a Run service credential or Client Manager component session calls an operator lifecycle endpoint without the required operator role
- **THEN** Platform MUST return an authorization failure and MUST NOT broaden that credential into an operator session
### Requirement: Platform persists and reconciles a real lifecycle state machine
Platform SHALL durably persist desired state, active and previous deployment references, component-key and deployment generations, job linkage, health summary, failure detail, and lifecycle timestamps for each server/profile installation.
#### Scenario: Lifecycle advances through real evidence
- **WHEN** build, deployment, registration, control, update, rollback, or uninstall work changes phase
- **THEN** Platform MUST transition only through valid requested, building, available, deploying, installed, registering, online, degraded, offline, updating, rolling_back, stopping, uninstalled, or failed states using durable job results, Run reports, or authenticated component heartbeats rather than local UI timers
#### Scenario: Platform restarts with in-flight work
- **WHEN** Platform restarts while a lifecycle job or component session is in progress
- **THEN** reconciliation MUST restore the persisted intent, project the durable job/session state idempotently, reject stale attempts, and either resume, retry, roll back, or fail safely without creating a duplicate activation
#### Scenario: Duplicate lifecycle request is retried
- **WHEN** the same actor repeats a request with the same idempotency key and immutable inputs
- **THEN** Platform MUST return the original installation/job result, while the same idempotency key with different immutable inputs MUST be rejected
### Requirement: Run deploys client managers through a checksummed controlled workspace
Run SHALL execute client-manager deployment only through the typed job contract and SHALL download, resume, verify, stage, and atomically activate an authorized distribution inside its configured client-manager workspace.
#### Scenario: Deployment completes after an interrupted transfer
- **WHEN** a current leased deployment downloads an available artifact in chunks and the transfer is interrupted
- **THEN** Run MUST persist offset and checksum state, resume without re-downloading acknowledged bytes, verify the final checksum and safe package layout, activate the staged slot, and report installed only after real activation succeeds
#### Scenario: Deployment payload or package is unsafe
- **WHEN** a deployment contains arbitrary commands, raw host paths, sockets, credentials, a stale attempt/deployment/key generation, a mismatched artifact/target/component, a checksum failure, traversal, symlink, device file, or unexpected executable layout
- **THEN** Run MUST reject or fail the job without changing the active slot and MUST return only bounded redacted diagnostics
#### Scenario: Deployment is cancelled or retried
- **WHEN** cancellation arrives between chunks or activation phases, a lease expires, or a retry uses the same idempotency and deployment generation
- **THEN** Run MUST honor the current fence, retain only safe resumable staging state, never let a stale attempt replace a newer activation, and converge on one recorded outcome
### Requirement: Client Manager authenticates as an independent component
Client Manager SHALL register with Platform using its own current component key and generation and SHALL receive a short-lived component session that is separate from Run control registration, job leases, credentials, and channels.
#### Scenario: Installed component registers successfully
- **WHEN** a deployed Client Manager signs a canonical registration request with a fresh timestamp and nonce and reports the active installation, artifact, version/revision, deployment generation, and declared capabilities
- **THEN** Platform MUST verify the same server/profile ownership, current component-key generation, active deployment, target/revision, signature, nonce, and capabilities, persist only a hash of a new expiring component session, return the token only to the component, and move the installation toward online health
#### Scenario: Registration signature is stale, replayed, revoked, or mismatched
- **WHEN** registration uses an expired timestamp, repeated nonce, revoked or previous-generation key, another server/component identity, inactive artifact, stale deployment generation, or undeclared capabilities
- **THEN** Platform MUST reject registration, record a safe denial audit, and MUST NOT create or reveal a component session
#### Scenario: Run identity is presented as Client Manager identity
- **WHEN** a caller presents a Run key, Run bearer session, Run job lease, or Run endpoint identity to the Client Manager registration or heartbeat contract
- **THEN** Platform MUST reject it and MUST NOT reuse Run authentication state
### Requirement: Component heartbeats drive safe health projection
Platform SHALL accept bounded heartbeat and capability reports only from a valid component session and SHALL project logical health and last-seen state without exposing local process details.
#### Scenario: Healthy component heartbeat arrives
- **WHEN** an unexpired, unrevoked session bound to the active installation reports a monotonic heartbeat with declared capabilities and a safe health code
- **THEN** Platform MUST update last seen and logical health idempotently and MUST expose only version, status, health code/reason, capabilities, and timestamps to authorized operators
#### Scenario: Heartbeat expires
- **WHEN** a component misses its declared heartbeat grace and offline thresholds
- **THEN** reconciliation MUST transition the installation from online to degraded and then offline using safe reasons while preserving the last successful deployment and audit history
#### Scenario: Session heartbeat is replayed or fenced
- **WHEN** a heartbeat sequence repeats, the session is expired/revoked, or its key, deployment, endpoint ownership, or artifact fence is no longer current
- **THEN** Platform MUST reject it without mutating health and require a new valid registration
### Requirement: Run performs bounded client-manager process control
Run SHALL start, stop, restart, and inspect a deployed Client Manager only through the plugin-declared executable and health contract and the typed lifecycle job.
#### Scenario: Operator starts or restarts a deployed component
- **WHEN** Platform dispatches an authorized current-generation control job whose action is declared by the profile
- **THEN** Run MUST supervise the fixed relative executable from the active slot, use bounded timeouts, persist the logical process state, and report progress and outcome without returning a PID, host path, environment secret, or socket
#### Scenario: Unsupported or stale control is requested
- **WHEN** a control action is undeclared, the installation is uninstalled, the attempt or deployment generation is stale, or another process already owns the active fence
- **THEN** Run MUST reject the operation idempotently without executing a command or disrupting the newer process
### Requirement: Updates are staged, health-checked, and rollback-safe
Platform and Run SHALL treat a Client Manager update as a same-installation transaction with explicit approval, compatible current-generation artifact selection, staged activation, bounded health confirmation, and a retained previous deployment.
#### Scenario: Compatible update becomes healthy
- **WHEN** an authorized operator approves a newer compatible artifact for the same server/profile/target and Run verifies, stages, activates, starts, and observes required health
- **THEN** Platform MUST set the new artifact/version as active, retain the prior deployment as rollback candidate, revoke the superseded component session, require new registration, and record real update progress and audit evidence
#### Scenario: Candidate update fails health
- **WHEN** download, checksum, activation, startup, registration, or health confirmation fails after an update begins
- **THEN** Run MUST preserve or restore the previous slot, Platform MUST project rolling_back and the real rollback result, and success MUST NOT be reported unless the restored deployment is active and healthy
#### Scenario: Invalid update or rollback is requested
- **WHEN** an artifact is revoked, from another server/profile/target, has a stale key generation, violates compatibility/version policy, or the previous slot no longer exists
- **THEN** Platform and Run MUST reject the request before activation and preserve the current deployment
### Requirement: Revocation and uninstall are safe and idempotent
Platform SHALL support session revocation and Run SHALL stop and uninstall a Client Manager without deleting server or shared files, while retaining Platform lifecycle and audit history.
#### Scenario: Key or session is revoked
- **WHEN** an authorized operator resets the component key, explicitly revokes the component session, reassigns ownership/endpoint, activates an update/rollback, or begins uninstall
- **THEN** Platform MUST revoke matching sessions, reject subsequent heartbeats, fence old artifacts/deployments as applicable, and show that rebuild/redeploy or registration is required
#### Scenario: Installed component is uninstalled
- **WHEN** an authorized operator confirms uninstall and Run completes the typed job
- **THEN** Run MUST stop the supervised process, remove only controlled active/previous/staging slots and local session/journal material for that installation, Platform MUST mark it uninstalled, and build/distribution/audit history MUST remain available
#### Scenario: Uninstall is repeated or interrupted
- **WHEN** uninstall is retried after partial cleanup, cancellation, lease expiry, or an already-uninstalled result
- **THEN** Run and Platform MUST converge idempotently without following links, escaping the configured workspace, or deleting game server/shared data
### Requirement: Lifecycle operations are durably audited and redacted
Platform SHALL record durable success, failure, and denial audits for build, deploy, register, start, stop, restart, update, rollback, revoke, retry, and uninstall using safe identifiers and bounded reasons.
#### Scenario: Lifecycle result is audited
- **WHEN** an operator, Run endpoint, or Client Manager performs or is denied a sensitive lifecycle action
- **THEN** the audit MUST include actor type and safe actor ID, server/profile/component, installation, job or artifact ID where applicable, operation, result, and redacted reason without raw keys, tokens, secret refs/values, credentials, paths, PIDs, sockets, endpoint addresses, DSNs, RCON passwords, or large output
### Requirement: Client Manager traffic remains isolated from Run channels
Client-manager registration, heartbeat, deployment transfer, process control, and optional game-client traffic SHALL remain separated from Run control heartbeat, job acknowledgement/result/cancel, log ingest, and artifact upload scheduling.
#### Scenario: Client-manager artifact transfer stalls
- **WHEN** a large or stalled client-manager download or component traffic stream is active
- **THEN** Run heartbeat, job ack/result/cancel polling, log spool upload, and unrelated artifact progress MUST continue independently within their bounded queues
### Requirement: Platform web provides a complete safe Client Manager workspace
platform_web SHALL provide authorized operators a Client Manager management workspace that reflects real backend state and preserves the existing black-mecha and magical-girl crystal-moonlight game-operations visual system.
#### Scenario: Operator manages the complete lifecycle
- **WHEN** an authorized operator opens Server Detail for a declared Client Manager
- **THEN** the UI MUST show safe profile/target/version/revision, build and artifact state, deployment/registration/online health, last seen, active/previous deployment, current job progress, permitted start/stop/restart, update/rollback, retry/redeploy after key reset, session revoke, and confirmed uninstall actions using real API projections
#### Scenario: Action is unavailable or destructive
- **WHEN** an action lacks permission, declaration, binding, online endpoint, capability, compatible artifact, current key generation, allowed lifecycle state, or confirmation
- **THEN** the UI MUST disable or hide it with a safe reason, require explicit confirmation for key reset/revoke/rollback/uninstall, preserve 401/403 handling, and MUST NOT fabricate progress or expose raw secrets, sessions, paths, PIDs, sockets, credentials, or endpoint addresses
@@ -0,0 +1,58 @@
## 1. Plugin Lifecycle Contracts
- [x] 1.1 Extend client-manager manifest and SDK types with safe version/revision, deployment, executable, lifecycle capability, health, compatibility, and update-policy declarations.
- [x] 1.2 Validate bounded relative executables, target/capability enums, timeouts, version rules, and reject arbitrary shell, traversal, raw secrets, endpoints, sockets, and credential-bearing declarations.
- [x] 1.3 Update SCUM and Minecraft example profiles, SDK bridge contracts, docs, and unsafe fixtures for complete lifecycle declarations and safe lifecycle requests/status.
- [x] 1.4 Add plugin manifest, SDK, and bridge tests covering accepted contracts, unsafe declarations, typed operations, and redaction.
## 2. Platform Durable Lifecycle Model
- [x] 2.1 Add domain/model/DTO types for installation states, action availability, deployment slots, health, desired/active/previous versions, lifecycle requests/results, component sessions, and replay nonces.
- [x] 2.2 Extend repository interfaces plus file and MySQL stores with durable client-manager installations, sessions, nonce fences, idempotent lookups, list/update/revoke operations, and safe persistence tests.
- [x] 2.3 Add validators for lifecycle transitions, action/target/version compatibility, deployment/control/update/rollback/uninstall inputs, component registration, heartbeat sequences, and redacted bounded results.
- [x] 2.4 Implement installation state transitions and terminal job projection using real durable job evidence, including idempotency, stale attempt/deployment/key fences, retryable failure, and active/previous deployment commits.
- [x] 2.5 Implement startup/periodic reconciliation for in-flight lifecycle jobs, expired sessions/nonces, heartbeat degraded/offline thresholds, restart recovery, and key-reset/endpoint-reassignment fencing.
## 3. Independent Component Identity
- [x] 3.1 Add canonical Client Manager registration signature and session contracts that are separate from Run control registration and job leases.
- [x] 3.2 Implement current component-key/generation signature verification, timestamp/nonce replay protection, ownership/artifact/target/revision/deployment/capability checks, hashed expiring session issuance, and denied audits.
- [x] 3.3 Implement component-session heartbeat authentication, monotonic sequence fencing, safe health projection, expiry/revocation, and explicit session revoke behavior.
- [x] 3.4 Add registration/session/heartbeat tests for current identity plus cross-owner/server/component/artifact/target/revision/key generation, expired, revoked, replayed, and Run-credential rejection paths.
## 4. Platform Job Orchestration and APIs
- [x] 4.1 Add typed client-manager deploy, control, update, rollback, and uninstall job kinds, payload validation, endpoint capability declarations, and safe job progress/result projection.
- [x] 4.2 Implement service authorization and action gating across actor role, server visibility, installed plugin/profile, runtime binding, endpoint online/capabilities, distribution availability/ownership/target/revision/key generation, and lifecycle state.
- [x] 4.3 Implement deploy/control/update/rollback/retry/revoke/uninstall services with durable intent-before-dispatch, idempotency, cancel/retry/stale-attempt handling, session fencing, and audit events.
- [x] 4.4 Add operator lifecycle summary/detail/action routes and component register/heartbeat routes with named DTOs, OpenAPI-style comments, session separation, safe errors, and API documentation.
- [x] 4.5 Add platform service/API tests covering owner/admin/service auth, 401/403, build-to-deploy, cross-boundary denial, restart reconcile, cancellation/retry/idempotency, health timeout, update rollback, key reset recovery, uninstall safety, auditing, and redaction.
## 5. Run Deployment and Supervision
- [ ] 5.1 Add Run protocol payloads and validation for client-manager deploy/control/update/rollback/uninstall, immutable fences, lifecycle progress/results, and endpoint capabilities.
- [ ] 5.2 Add a scoped client-manager workspace and durable local journal for installation slots, chunk offsets/checksums, deployment/attempt/key generations, idempotency outcomes, process state, and restart reconciliation.
- [ ] 5.3 Implement resumable artifact download, checksum verification, safe archive extraction, staging, atomic active/previous activation, cancellation checkpoints, and rejection of traversal/symlinks/device files/unexpected layouts.
- [ ] 5.4 Implement bounded declarative client-manager start/stop/restart/status supervision with fixed relative executable, safe timeouts, logical health, and no path/PID/socket projection.
- [ ] 5.5 Implement staged update health confirmation, automatic rollback, explicit rollback, stale/revoked generation rejection, re-entry after restart, and real phase reporting.
- [ ] 5.6 Implement idempotent safe uninstall that stops the process and deletes only controlled installation slots/journal/session material without following links or touching server/shared files.
- [ ] 5.7 Add Run tests for deploy resume/checksum, fences, cancel/retry/stale attempts, reconciliation, supervision, health failure rollback, uninstall safety, redaction, and channel isolation under stalled client-manager traffic.
## 6. platform_web Lifecycle Workspace
- [ ] 6.1 Add API types, schemas, client methods, safe action projections, polling/job progress integration, and tests for Client Manager lifecycle summaries and commands.
- [ ] 6.2 Build a rich Server Detail Client Manager workspace showing build/artifact, desired/active/previous version, deployment/registration/online health, last seen, real current job phases, retry guidance, and action availability.
- [ ] 6.3 Add start/stop/restart, deploy/redeploy, update/rollback, session revoke, key reset recovery, retry, and uninstall confirmation/error flows while preserving compact server action menus and both existing themes.
- [ ] 6.4 Add frontend tests and browser acceptance for full state/action coverage, real progress/failure recovery, destructive confirmations, 401/403 behavior, responsive layouts, theme preservation, and secret/path/PID/socket redaction.
## 7. Documentation and Verification
- [ ] 7.1 Update Platform, Run, plugins, SDK, platform_web, route, domain, protocol, and deployment docs with lifecycle states, security/session boundaries, operations, recovery, and explicit production non-goals.
- [ ] 7.2 Run plugin manifest validation, plugin SDK/tests/typecheck, Platform `go test -count=1 ./...`, independent Run `go test -count=1 ./...`, and focused race/restart checks where practical.
- [ ] 7.3 Run platform_web tests, typecheck, production build, and a browser walkthrough for the touched Server Detail and server action workflows in both visual themes.
- [ ] 7.4 Run shell/compose checks, `scripts/check-structure.sh`, and `git diff --check` in both the main repository and independent Run checkout.
- [ ] 7.5 Run `openspec validate implement-secure-client-manager-lifecycle --strict` and record all verification evidence below before marking implementation complete.
## Verification Evidence
Pending implementation and verification.