Complete platform management workflows

This commit is contained in:
npc0-hue
2026-07-14 16:39:37 +08:00
parent 7e05d0a4e7
commit 4f33f761a3
106 changed files with 11313 additions and 460 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-13
@@ -0,0 +1,65 @@
## Context
The platform already has separate run control, job, log, and artifact channels. Plugin manifests currently declare lifecycle, file, log, artifact, and AI capabilities, but they do not describe whether a server may be reached by FTP, rsync, or run, nor do they declare run-only operations such as remote database reads or RCON. The previous SCUM codebase used FTP/SFTP workers for file upload, scum_run for server-side operations, SQLite query forwarding, log transfer, and game-client command handling; this change brings those ideas into the new platform as typed, plugin-declared capabilities.
## Goals / Non-Goals
**Goals:**
- Model remote access methods and remote run operations in the plugin manifest.
- Require installed plugins to declare remote capabilities before platform bridge or direct job dispatch can queue them.
- Keep remote file/database/RCON/log operations behind platform and run channels.
- Allow both SCUM and Minecraft plugins to declare compatible remote access needs.
- Keep job payloads bounded: logical target keys, scoped input/artifact refs, and safe result refs only.
**Non-Goals:**
- No raw FTP, rsync, database, or RCON credentials in plugin manifests or plugin pages.
- No browser-to-run, plugin-to-run, or plugin-to-database direct connection.
- No production FTP/rsync client, MySQL client, SQLite parser, or RCON protocol implementation in this change.
- No cloud host provider workflow or server rental/billing feature.
## Decisions
### Decision 1: Manifest declares methods and capabilities separately
`remoteAccess.methods` describes how a server may be reached (`ftp`, `rsync`, `run`). `remoteAccess.runCapabilities` lists the exact run operations the plugin can use. This keeps transport choice visible while still preserving the existing run capability matching model.
Alternative considered: encode everything as free-form tags. Rejected because marketplace and authorization need deterministic validation and filtering.
### Decision 2: Remote access uses a dedicated bridge action
Plugin pages use `remote.access.request` for database, RCON, log transfer, and remote file jobs. Existing `files.request` remains for generic scoped file operations; lifecycle `jobs.dispatch` remains for start/stop. The new action lets platform apply a distinct `server.remote.access` permission and capability declaration check.
Alternative considered: overload `jobs.dispatch` for every remote operation. Rejected because RCON/database/log transfer should not be authorized only by `server.lifecycle`.
### Decision 3: Direct server-bound jobs are plugin-gated
When a job includes a `serverInstanceId`, platform validates the instance plugin declares the requested capability. This prevents callers from bypassing plugin bridge and enabling remote DB/RCON/log transfer jobs on plugins that did not opt in.
Alternative considered: enforce declaration only in plugin bridge. Rejected because platform API callers can create jobs directly in tests and future admin flows.
### Decision 4: Run remote executor is bounded metadata first
Run reports remote capabilities and accepts remote jobs, but returns safe metadata/result refs rather than opening real network connections in this change. Real FTP/rsync/database/RCON adapters can later attach behind the same job envelopes without changing plugin manifests.
Alternative considered: implement protocol clients now. Rejected because credential storage, network policy, and result artifact formats need a separate change and should not be rushed into manifest plumbing.
## Risks / Trade-offs
- [Risk] Operators may expect real FTP/rsync/DB/RCON execution immediately. Mitigation: docs and result messages state this is the declared, bounded job contract; adapter implementation remains a follow-up.
- [Risk] Capability names may grow numerous. Mitigation: keep them grouped under `remote.*` and validate them centrally.
- [Risk] Existing tests using generic jobs may fail once server-bound jobs are plugin-gated. Mitigation: lifecycle/file capabilities remain declared in existing test plugin fixtures.
## Migration Plan
1. Add OpenSpec, schema, domain, DTO, validator, and service support for remote access declarations.
2. Update SCUM and add Minecraft example manifests with declared remote access.
3. Extend run protocol and runtime to validate/report remote capabilities and complete bounded remote jobs.
4. Add tests for manifest validation, platform authorization, direct job gating, and run remote job handling.
5. Run manifest validation, platform/run tests, structure check, and strict OpenSpec validation.
## Open Questions
- Which follow-up change should own real FTP/rsync credential storage and connection testing?
- Should RCON results become log entries, artifacts, or both when full adapters land?
@@ -0,0 +1,29 @@
## Why
The platform needs one safe model for remote game server access across hosted files, run-managed hosts, databases, logs, and RCON. The old SCUM stack handled FTP/SFTP, run-side process control, SQLite queries, logs, and client commands in separate paths; the new platform must make those abilities plugin-declared before they can be used.
## What Changes
- Add plugin manifest metadata for declared remote access methods: `ftp`, `rsync`, and `run`.
- Add remote run capabilities for remote file read/write, process start/stop, MySQL and SQLite query, log transfer, and RCON command dispatch.
- Add platform registry and marketplace projection fields so operators can see which remote access methods a game plugin enables.
- Add a platform-mediated bridge action for remote access requests that queues only capabilities declared by the installed plugin.
- Extend run capability reporting and bounded remote job handling so MC and SCUM plugins can opt into the same contract.
- Add first-party Minecraft and SCUM example manifests proving the shared declaration model.
## Capabilities
### New Capabilities
- `plugin-declared-remote-access`: Plugin-declared remote server access through ftp, rsync, or run with scoped run jobs for remote files, lifecycle, database reads, log transfer, and RCON.
### Modified Capabilities
- None.
## Impact
- Affects `plugins/` manifest schema, manifest validator tests, and first-party example manifests.
- Affects `platform/` domain, DTO, validators, service bridge dispatch, marketplace projections, docs, and tests.
- Affects `run/` protocol capability constants, job validation, runtime capability reporting, worker execution, docs, and tests.
- Does not add billing, cloud host sales, plugin-owned credentials, browser-to-run access, raw host paths, or raw database/RCON credentials in plugin pages.
@@ -0,0 +1,56 @@
## ADDED Requirements
### Requirement: Plugin manifests declare remote access methods
Game management plugin manifests SHALL declare remote access methods before platform exposes FTP, rsync, or run-mediated remote server operations for server instances created from that plugin.
#### Scenario: Manifest declares supported methods
- **WHEN** a plugin manifest lists `ftp`, `rsync`, or `run` under remote access methods
- **THEN** platform registry and marketplace responses MUST preserve those methods without exposing host paths, remote credentials, direct sockets, or provider secrets
#### Scenario: Unsafe remote access declaration is rejected
- **WHEN** a plugin manifest includes raw credentials, host paths, direct run socket details, or unknown remote access methods
- **THEN** plugin workspace validation and platform registration MUST reject the manifest before it becomes installable
### Requirement: Remote run operations are capability gated
Remote run operations SHALL be represented as explicit run capabilities and SHALL require both the run endpoint and the installed game plugin to declare the requested capability.
#### Scenario: Declared remote run job is queued
- **WHEN** a plugin declares a remote run capability and the selected run endpoint reports the same capability
- **THEN** platform MAY queue a bounded job for that server instance using logical target keys and scoped input or artifact refs
#### Scenario: Undeclared remote run job is denied
- **WHEN** a caller requests remote database, RCON, log transfer, or remote file work for a server instance whose plugin did not declare the requested capability
- **THEN** platform MUST reject or deny the request before creating a job
### Requirement: Remote access bridge is platform mediated
Plugin pages SHALL request remote access through a platform-mediated bridge action and MUST NOT connect directly to FTP, rsync, run, MySQL, SQLite, log storage, or RCON endpoints.
#### Scenario: Bridge queues declared remote access
- **WHEN** a plugin page has `server.remote.access` permission and requests `remote.access.request` for a declared capability
- **THEN** platform MUST authorize the action and queue the corresponding bounded run job
#### Scenario: Bridge denies undeclared remote access
- **WHEN** a plugin page requests `remote.access.request` for a capability not declared by the plugin
- **THEN** platform MUST return a safe denial and MUST NOT expose run credentials, host paths, database DSNs, RCON passwords, or remote storage endpoints
### Requirement: Run handles bounded remote jobs
Run SHALL report supported remote capabilities and complete remote job assignments with bounded progress and safe result references while keeping control, job, logs, and artifact channels separate.
#### Scenario: Run accepts remote database and RCON assignments
- **WHEN** run receives declared remote MySQL, SQLite, RCON, log transfer, or remote file assignments
- **THEN** run MUST validate bounded job metadata and return terminal results without embedding raw credentials, host paths, query result bodies, log bodies, or RCON output in the job result payload
#### Scenario: Run rejects unsafe remote job payload
- **WHEN** a remote job assignment includes an absolute path, parent traversal, raw secret, direct socket, or oversized inline content
- **THEN** run MUST reject the assignment with a bounded failure result
### Requirement: MC and SCUM plugins share the remote access model
First-party Minecraft and SCUM plugin manifests SHALL validate against the same remote access schema and declare only the capabilities each game needs.
#### Scenario: Minecraft plugin validates
- **WHEN** the Minecraft example plugin declares run-managed files, logs, and RCON access
- **THEN** plugin workspace manifest validation MUST pass
#### Scenario: SCUM plugin validates
- **WHEN** the SCUM example plugin declares FTP/rsync/run file access, run lifecycle, SQLite/MySQL database read compatibility, log transfer, and RCON access
- **THEN** plugin workspace manifest validation MUST pass
@@ -0,0 +1,40 @@
## 1. OpenSpec Contracts
- [x] 1.1 Create proposal, design, and spec for plugin-declared remote access.
- [x] 1.2 Validate the new change artifacts with `openspec validate --strict`.
## 2. Plugin Manifest Contracts
- [x] 2.1 Extend the game plugin manifest schema with `remoteAccess` methods, run capabilities, database engines, RCON, and log transfer declarations.
- [x] 2.2 Update manifest validation tests and examples so SCUM and Minecraft validate with remote access declarations.
## 3. Platform Registry and Authorization
- [x] 3.1 Add domain and DTO remote access metadata to game plugin, manifest, and marketplace projections.
- [x] 3.2 Extend platform validators for remote methods, remote run capabilities, `server.remote.access`, and `remote.access.request`.
- [x] 3.3 Gate server-bound jobs against the server instance plugin's declared capabilities.
- [x] 3.4 Add bridge execution for declared remote access requests and tests for denied undeclared capabilities.
## 4. Run Protocol and Worker
- [x] 4.1 Add remote run capability constants and validation rules for bounded remote assignments.
- [x] 4.2 Report remote capabilities from run smoke and worker mode.
- [x] 4.3 Add bounded remote job execution results that keep heavy payloads in artifact/log channels.
- [x] 4.4 Add run tests for remote DB/RCON/log/file capabilities and unsafe payload rejection.
## 5. Documentation and Verification
- [x] 5.1 Update platform, run, and plugin docs for remote access capability declarations.
- [x] 5.2 Run plugin manifest validation, platform tests, run tests, and `scripts/check-structure.sh`.
- [x] 5.3 Record verification evidence in `tasks.md`.
## Evidence
- `openspec validate add-plugin-declared-remote-access --strict` - passed; PostHog telemetry flush logged DNS warnings only after validation succeeded.
- `go test ./...` in `platform/` - passed.
- `go test ./...` in `run/` - passed.
- `npm test` in `plugins/` - passed: 14 manifest/SDK tests.
- `npm run typecheck` in `plugins/` - passed.
- `TMPDIR=/private/tmp npm run validate:manifest` in `plugins/` - passed for dev, SCUM, and Minecraft manifests.
- `scripts/check-structure.sh` - passed.
- `git diff --check` - passed.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-13
@@ -0,0 +1,103 @@
## Context
The platform already has control, job, log, and artifact channels, plus plugin-declared remote access capabilities for FTP, rsync, run-mediated files, SQL, logs, and RCON. The missing layer is operational delivery: operators need to generate a per-server run executable, download it for a selected OS/architecture, authenticate it with the server's current database-backed run key, update it after it is online, and let plugins declare how run finds and controls the actual game server.
The old SCUM stack has useful patterns: a run-side process controller, a separate client/robot manager for cases where server control requires a game client or custom automation, Git-based source updates, Go toolchain checks, FTP log polling, SQLite reads, and command forwarding. This design generalizes those patterns without making SCUM special in platform core.
## Goals / Non-Goals
**Goals:**
- Let server owners generate and download a server-scoped run package from the server list or server action menu.
- Store one current run key and one current client-manager key per server/component in the database, encrypted at rest, with redacted secret references in APIs and logs.
- Let online run endpoints self-update through a platform job that stages, verifies, swaps, and reports rollback-safe status.
- Let plugins declare runtime profiles that explain how to find a server, start/stop it, check dependencies, install missing dependencies, collect live and historical logs, and expose files, FTP/rsync, SQL, and RCON.
- Let plugins declare optional client-manager build profiles for cases like SCUM where a separate executable must be compiled from an open repository with a distinct authentication key.
- Keep all browser and plugin operations platform-mediated and preserve channel isolation for control, jobs, logs, files, and artifacts.
**Non-Goals:**
- No billing, cloud host sales, server rental marketplace, or cloud-provider provisioning workflow.
- No raw run keys, client-manager keys, FTP passwords, database DSNs, RCON passwords, direct sockets, or host paths in plugin pages or platform_web responses.
- No arbitrary plugin shell scripts for dependency installation or build execution.
- No requirement that every game use run; FTP-only, FTP+RCON, and custom-client modes remain valid when declared by the plugin.
- No production package-signing infrastructure beyond local checksums/signature hooks in the first implementation.
## Decisions
### Decision 1: Distribution artifacts are secret-bearing platform records
Platform stores generated run and client-manager packages as artifacts with a distribution record containing kind, server instance, plugin ID, target OS/architecture, source revision, checksum, status, component kind, and key generation. The package config contains the current active key for that server/component because the remote executable must authenticate with it. API responses, logs, job payloads, plugin SDK payloads, and UI state expose only artifact IDs, key generation, and redacted secret refs.
Alternative considered: ship one global run binary and ask users to hand-edit config files. Rejected because it causes copy/paste key exposure, weak auditability, and poor operator experience.
### Decision 2: Run and client-manager credentials are separate singleton keys
Each server/component has exactly one active run key and, when needed, exactly one active client-manager key. Run and client-manager keys remain different secrets, but platform does not keep multiple simultaneously valid keys for the same component. Resetting a key replaces the encrypted database value, increments the key generation, invalidates every older run or client package for that component, and requires regenerating and redeploying the affected package.
Alternative considered: reuse the run key for plugin client managers. Rejected because client managers may have broader game-specific control surfaces and need independent reset, revocation, and audit.
Alternative considered: issue temporary enrollment tokens and exchange them for runtime keys. Rejected because the desired operator model is a single database-backed current key per server/component, with explicit reset when trust must be revoked.
### Decision 3: Plugins declare runtime profiles, not raw local paths
Plugins define runtime profiles with logical server discovery probes, lifecycle actions, dependency probes, dependency install plans, log sources, transport profiles, and optional client-manager profiles. Operators bind those logical keys to a server instance at setup time. Run resolves bindings locally and returns logical status, not raw host paths.
Alternative considered: hardcode Minecraft and SCUM discovery rules into platform. Rejected because the platform should remain a game server management core, while game-specific control knowledge belongs in plugins.
### Decision 4: Dependency install is typed and reviewable
Dependency checks are read-only probes such as command version, service existence, port availability, file presence under scoped roots, Steam app presence, Java version, Docker availability, or Windows package presence. Install plans are typed steps with approved package managers or verified downloads. Platform shows the plan and queues it only after operator approval.
Alternative considered: let plugins provide arbitrary install shell scripts. Rejected because it creates an unrestricted execution path and conflicts with run security rules.
### Decision 5: Client-manager builds are source-pinned build jobs
Plugin client-manager profiles declare a repository URL, branch/tag or pinned revision policy, supported targets, build system, config template keys, dependency hints, and produced artifact paths. Platform creates a build job in an isolated workspace or future build worker, redacts secrets from logs, writes generated config from secret refs, and publishes a downloadable artifact.
Alternative considered: require plugin authors to upload prebuilt binaries only. Rejected because SCUM-style managers need reproducible platform-side injection of per-server config and keys.
### Decision 6: Run owns local execution and transport adapters
Run is the multi-platform server launcher and transport agent. It starts/stops third-party programs through plugin lifecycle profiles, tails stdout/stderr and declared log files, transfers files through the artifact channel, and performs declared FTP/rsync, SQL, and RCON operations through scoped adapters. Long transfers must not block heartbeat, job ack/result, or log ingest.
Alternative considered: let platform_web or plugin pages connect directly to FTP/RCON/SQL. Rejected because that exposes credentials and bypasses platform authorization, audit, and channel isolation.
### Decision 7: Live and historical logs share durable sequence semantics
Run streams live process output and file tails through the log channel with source IDs and monotonically increasing sequences. Historical logs are fetched through backfill jobs that use checkpoints, file fingerprints, FTP polling cursors, or database cursors to avoid duplicates. Platform_web displays live tail and history through platform APIs only.
Alternative considered: return log bodies inside job results. Rejected because logs can be large and must not compete with control and job metadata.
### Decision 8: Self-update is staged and rollback-safe
When run is online and supports the update capability, platform queues an update job with an artifact ref and checksum. Run downloads via the artifact channel, verifies checksum/signature metadata, stages the new binary, drains or rejects new local work, swaps atomically where supported, restarts, and reports success or rollback failure. Offline endpoints keep the latest downloadable package for manual replacement.
Alternative considered: send a raw command to pull the latest repository. Rejected because it is platform-specific, hard to verify, and unsafe to audit.
## Risks / Trade-offs
- [Risk] Build jobs can execute untrusted repository code. Mitigation: require plugin-declared build profiles, pinned refs, isolated workspaces, bounded logs, and a later sandboxed build worker before public plugin builds.
- [Risk] Self-update can leave a remote run offline. Mitigation: stage artifacts, verify checksums, retain previous binary, report last-known version, and keep manual download available.
- [Risk] Dependency install plans differ across Windows, Linux, and macOS. Mitigation: model probes and install steps per target platform, and show unsupported targets before dispatch.
- [Risk] Historical log backfill can duplicate records. Mitigation: persist per-source checkpoints with file fingerprints, offsets, sequence acknowledgements, and cursor metadata.
- [Risk] Resetting a key immediately breaks deployed run or client-manager binaries. Mitigation: make reset confirmations explicit, mark old packages revoked, show that regeneration is required, and keep online update/manual download paths visible.
- [Risk] Operators may expect plugin profiles to work without binding server-specific values. Mitigation: require server setup validation before showing actions that depend on missing bindings.
## Migration Plan
1. Extend plugin manifest schema and examples with runtime profiles, dependency probes, log sources, transport profiles, and client-manager build profiles.
2. Add platform domain, model, DTO, validator, and service support for distribution records, encrypted database key storage, key reset, key generation checks, build jobs, dependency status, runtime bindings, and update jobs.
3. Add run package config loading, registration authentication against the current database key generation, dependency probes, discovery probes, log source checkpoints, transport adapter envelopes, and self-update executor.
4. Add platform_web server-list and server-detail action menus for generate/download/update run, generate/download client manager, dependency checks, live logs, and historical logs.
5. Add tests and docs across plugins, platform, run, and platform_web; validate with OpenSpec, structure checks, backend tests, plugin validation, run tests, frontend tests, and browser walkthroughs for touched UI.
Rollback removes the new distribution/client-manager routes and UI actions, leaves existing run endpoints and plugin-declared remote access behavior intact, and preserves already-created artifacts as inert downloadable records until manually cleaned.
## Open Questions
- Which envelope-key source should protect the encrypted key columns stored in the platform database?
- Should platform-side builds run in the platform process for the first version, or require a separate build worker from day one?
- What default retention should apply to historical logs and generated binaries?
- Which target packaging formats should be first-class first: zip/tar.gz only, or Windows service installer, systemd unit bundle, and launchd plist bundles?
- Should plugin client-manager profiles support private repositories later, and if so how should source credentials be stored and audited?
@@ -0,0 +1,30 @@
## Why
Run is becoming the platform's cross-platform server launcher and transport agent, but operators still need a safe way to generate, download, authenticate, update, and observe per-server run binaries. Some games also need plugin-declared companion clients, such as SCUM-style client managers, that are built from plugin-provided source repositories with separate credentials and lifecycle from run.
## What Changes
- Add a platform-managed run distribution workflow from the server list or server actions menu: generate executor, choose target OS/architecture, write the current server/component authentication key into the generated package config, download the artifact, and store the single active encrypted key in the database.
- Add run self-update orchestration: if an assigned run is already online, platform can enqueue an update command that instructs the remote run to pull or replace itself with the latest approved run build.
- Add plugin-declared external controller/client-manager build profiles for games that cannot be controlled only through run, FTP, SQL, logs, and RCON.
- Add separate database-backed active keys for run and plugin-declared client managers; resetting a server's run or client key invalidates every previous package and requires regenerating the corresponding run or client artifact.
- Extend plugin manifests with server discovery, dependency checks, dependency install guidance, log source declarations, historical log retention hints, and transport wiring so run knows how to find and manage the target server without hardcoded game logic.
- Add UI/API contracts for server action menu entries: generate run, download latest run package, push run update, generate plugin client manager, inspect dependency status, open live logs, and browse historical logs.
## Capabilities
### New Capabilities
- `run-distribution-and-client-managers`: Platform-managed run packaging, download, key provisioning, remote self-update, plugin-declared companion client builds, dependency checks, server discovery, and live/historical observability.
### Modified Capabilities
- None.
## Impact
- Affects `plugins/` manifest schema, SDK docs, SCUM and Minecraft example manifests, and validation tests.
- Affects `platform/` domain, DTOs, encrypted secret references, build records, artifact records, run endpoint provisioning, job creation, audit events, and API routes.
- Affects `run/` generated package config, updater job handling, dependency probes, server discovery adapters, live log tailing, historical log checkpoints, file/FTP/SQL/RCON transport adapters, and docs.
- Affects `platform_web/` server list and server detail actions, live log views, historical log views, dependency status surfaces, and browser walkthrough coverage.
- Does not add billing, host rental, cloud host sales, raw credential exposure, plugin-owned direct sockets, or unrelated SaaS marketplace workflows.
@@ -0,0 +1,133 @@
## ADDED Requirements
### Requirement: Platform generates server-scoped run packages
The platform SHALL let an authorized operator generate a run package for a selected server instance and target platform using the server's single current run key stored encrypted in the platform database.
#### Scenario: Operator generates run from server actions
- **WHEN** an authorized operator selects generate executor for a server instance and chooses a supported OS/architecture
- **THEN** platform MUST create or reuse the server's current encrypted run key, write that key into the generated package config, create a distribution record with key generation, build/download artifact, checksum metadata, and audit event, and MUST NOT return the raw key in the API response
#### Scenario: Operator downloads generated run package
- **WHEN** an authorized operator downloads a generated run artifact
- **THEN** platform MUST authorize access by server scope and return the secret-bearing package through artifact/download APIs without exposing raw host paths, direct sockets, or database credentials in package metadata
### 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.
#### 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, 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
- **THEN** platform MUST reject the old key and require the operator to regenerate and redeploy the corresponding run or client-manager package
### Requirement: Plugins declare runtime profiles
Game plugins SHALL declare runtime profiles that describe how run or external transports can discover, control, observe, and connect to the game server using logical keys instead of raw credentials or host paths.
#### Scenario: Plugin declares server discovery and transports
- **WHEN** a plugin manifest declares runtime profiles with discovery probes, lifecycle actions, dependency probes, log sources, FTP/rsync, SQL, RCON, or client-manager bindings
- **THEN** plugin validation MUST accept only known profile fields and platform MUST preserve the declarations for server setup and action gating
#### Scenario: Plugin manifest includes unsafe runtime details
- **WHEN** a plugin manifest embeds raw run keys, client-manager keys, FTP passwords, database DSNs, RCON passwords, absolute host paths, direct sockets, or arbitrary shell scripts in runtime profiles
- **THEN** plugin validation and platform registration MUST reject the manifest before it becomes installable
### Requirement: Server runtime bindings resolve plugin profiles
Server instances SHALL bind plugin-declared logical runtime keys to operator-provided local or remote settings before run-dependent actions are enabled.
#### Scenario: Run discovers an existing server
- **WHEN** run registers for a server instance with complete runtime bindings and the plugin declares discovery probes
- **THEN** run MUST evaluate the probes locally, report logical discovery status, version, and health, and MUST NOT return raw host paths or secret values to platform_web or plugin pages
#### Scenario: Required binding is missing
- **WHEN** an operator opens server actions for a runtime profile that requires unbound install root, service name, FTP profile, SQL profile, RCON profile, or client-manager profile
- **THEN** platform MUST mark dependent actions unavailable and explain the missing logical binding without exposing internal storage details
### Requirement: Plugins control third-party startup behavior
Third-party game program startup and shutdown SHALL be driven by plugin-declared lifecycle profiles and server runtime bindings, not hardcoded platform game logic.
#### Scenario: Local process server starts through run
- **WHEN** a plugin declares a local process lifecycle profile and the server runtime binding is complete
- **THEN** run MUST start or stop the third-party program through the declared bounded action template and stream stdout/stderr through the log channel
#### Scenario: Hosted server has no local lifecycle control
- **WHEN** a plugin declares an FTP-only, FTP+RCON, or custom-client runtime profile without local process lifecycle
- **THEN** platform MUST hide or deny local start/stop actions and expose only the declared remote or client-manager actions
### Requirement: Dependency checks and installs are typed
Run SHALL check dependencies through plugin-declared probes and SHALL install missing dependencies only through approved, typed, reviewable install plans.
#### Scenario: Dependency check reports missing runtime
- **WHEN** run evaluates plugin-declared dependency probes and a required runtime, service, package, toolchain, Steam app, Java runtime, Docker runtime, or OS package is missing
- **THEN** platform MUST show dependency status and a reviewable install plan if the plugin declares one for the target platform
#### Scenario: Dependency install is approved
- **WHEN** an authorized operator approves a dependency install plan
- **THEN** platform MUST queue a bounded run job using typed package/download steps, checksum or source metadata where provided, and must reject arbitrary shell snippets
### 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.
#### 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, and output artifact paths
- **THEN** platform MUST create a build job that checks out the approved source, injects redacted configuration from secret refs, produces a downloadable artifact, and redacts secrets from build logs
#### 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
### Requirement: Online run endpoints self-update through platform jobs
The platform SHALL update online run endpoints by queuing a bounded self-update job that references an approved artifact and checksum instead of sending raw shell commands.
#### Scenario: Online run accepts update
- **WHEN** an assigned run endpoint is online and supports self-update
- **THEN** platform MUST queue an update job, and run MUST download the artifact, verify checksum or signature metadata, stage the replacement, report progress, and restart or swap only after verification succeeds
#### Scenario: Update verification fails
- **WHEN** run cannot verify or stage the update artifact
- **THEN** run MUST keep the current executable, report a bounded failure result, and preserve heartbeat or last-known status without leaking local paths or credentials
### Requirement: Run exposes multi-channel transport capabilities
Run SHALL provide declared server operations through separate control, job, log, artifact/file, FTP/rsync, SQL, and RCON channels or adapters while preserving priority and bounded payload rules.
#### Scenario: Long file transfer is active
- **WHEN** run is transferring a large file, FTP payload, rsync payload, or artifact chunk
- **THEN** heartbeat, job ack/result, cancellation polling, and log ingest MUST continue independently without waiting for transfer completion
#### Scenario: Undeclared transport operation is requested
- **WHEN** a plugin page or platform caller requests FTP, SQL, RCON, file, or process work not declared by the plugin runtime profile and run capabilities
- **THEN** platform MUST deny the request before creating a job and MUST return only a safe error
### Requirement: Live and historical logs are platform-mediated
Platform_web SHALL show live and historical server logs through platform APIs backed by run log ingest, log checkpoints, and plugin-declared log sources.
#### Scenario: Live log tail is opened
- **WHEN** an operator opens live logs for a server with an online run endpoint
- **THEN** platform_web MUST read from platform log APIs and display sequenced log entries from run without direct run sockets or raw file paths
#### Scenario: Historical log backfill is requested
- **WHEN** an operator requests older logs for a declared process, file, FTP, SQL, or plugin-specific log source
- **THEN** platform MUST queue or serve a backfill using per-source checkpoints, cursors, or file fingerprints and MUST avoid embedding large log bodies in job result payloads
### Requirement: Server action menu reflects declared availability
The server list and server detail action menu SHALL show generate run, download run, push run update, generate client manager, dependency check, install dependency, live logs, and historical logs only when the current user and plugin/runtime state permit them.
#### Scenario: Actions are available
- **WHEN** a server has a plugin with runtime profiles, complete bindings, and the current user has the required permissions
- **THEN** platform_web MUST render the applicable actions using the existing game-operations console style and call platform APIs rather than plugin-owned direct endpoints
#### Scenario: Actions are unavailable
- **WHEN** a server lacks a required plugin declaration, binding, online run status, build profile, or user permission
- **THEN** platform_web MUST hide or disable the action with a safe reason and MUST NOT render raw credentials, host paths, direct sockets, or secret refs beyond redacted identifiers
### Requirement: Distribution and control events are audited
The platform SHALL audit run generation, run download, credential reset, run update, dependency install, client-manager build, client-manager download, and transport operation requests.
#### Scenario: Sensitive operation completes
- **WHEN** a sensitive distribution or control operation succeeds, fails, or is denied
- **THEN** platform MUST record actor, server instance, plugin ID, component kind, operation, result, artifact ID or job ID where applicable, and redacted reason without raw secret material
@@ -0,0 +1,70 @@
## 1. Plugin Contracts
- [x] 1.1 Extend the game plugin manifest schema with runtime profiles for server discovery, lifecycle profiles, dependency probes, install plans, log sources, transport profiles, and client-manager build profiles.
- [x] 1.2 Update plugin SDK types and bridge docs for runtime bindings, run distribution actions, dependency actions, live/historical log actions, and client-manager generation.
- [x] 1.3 Update SCUM and Minecraft example manifests to declare realistic runtime profiles, dependency probes, log sources, and transport bindings.
- [x] 1.4 Add plugin validation tests that accept safe runtime/client-manager profiles and reject raw keys, database DSNs, RCON passwords, direct sockets, raw host paths, and arbitrary shell snippets.
## 2. Platform Secret and Distribution Model
- [x] 2.1 Add platform domain, DTO, model, repository, and validator types for run distributions, client-manager distributions, runtime bindings, encrypted database keys, key generations, dependency status, build jobs, and update jobs.
- [x] 2.2 Implement encrypted-at-rest database key storage for exactly one active run key and one active client-manager key per server/component.
- [x] 2.3 Add key reset services and tests proving reset replaces the active encrypted key, increments generation, revokes old packages, and requires regenerating the affected run or client-manager artifact.
- [x] 2.4 Add services and tests for generating server-scoped run packages, creating artifact records, writing the current run key into package config, storing key generation metadata, and authorizing downloads.
- [x] 2.5 Add services and tests for client-manager build records, distinct current client-manager keys, source revision metadata, target-platform validation, and downloadable artifact publication.
- [x] 2.6 Add audit events for generation, download, key reset, update, dependency install, build, and denied sensitive operations.
## 3. Platform APIs and Job Orchestration
- [x] 3.1 Add API routes and handlers for server action availability, generate/download run, reset run key, push run update, generate/download client manager, reset client-manager key, check dependencies, install dependencies, live logs, and historical logs.
- [x] 3.2 Gate all routes by user permissions, server ownership, plugin declarations, runtime bindings, and run endpoint capability availability.
- [x] 3.3 Add self-update job creation with artifact refs, checksums, idempotency keys, and denied-path tests for offline or unsupported run endpoints.
- [x] 3.4 Add dependency-check and dependency-install job creation with typed install plans and rejection of arbitrary shell commands.
- [x] 3.5 Add historical log backfill job creation with source IDs, checkpoints, bounded results, and artifact/log channel separation.
## 4. Run Bootstrap and Runtime Behavior
- [x] 4.1 Implement generated package config loading, current key generation authentication, server-scoped identity, old-package rejection after reset, and redacted local diagnostics.
- [x] 4.2 Implement runtime profile resolution for local process, hosted FTP/RCON, FTP-only, SQL, file, and custom-client modes using server bindings.
- [x] 4.3 Implement dependency probes and typed install plan execution for supported OS targets with safe progress and failure results.
- [x] 4.4 Implement self-update executor with artifact download, checksum/signature verification hooks, staging, rollback, restart/swap behavior, and tests.
- [x] 4.5 Implement live log tailing from process stdout/stderr and declared file sources with durable sequence checkpoints.
- [x] 4.6 Implement historical log backfill cursors for declared file, FTP, SQL, and plugin-specific log sources without embedding large log bodies in job results.
- [x] 4.7 Implement bounded adapter envelopes for FTP/rsync, SQL read, RCON command, and file transfer so long transfers do not block heartbeat or job metadata.
## 5. Build Pipeline
- [x] 5.1 Implement platform-side or build-worker source checkout for plugin-declared client-manager repositories with pinned revision metadata.
- [x] 5.2 Implement target-platform validation, build dependency checks, redacted config injection, bounded build logs, checksum calculation, and artifact publication.
- [x] 5.3 Add SCUM-style client-manager build tests covering supported targets, unsupported target denial, separate credential injection, and redacted logs.
## 6. platform_web Workflows
- [x] 6.1 Add server list and server detail action menu entries for generate run, download run, push run update, generate client manager, dependency check/install, live logs, and historical logs.
- [x] 6.2 Add API client types, schemas, and tests for run distribution, client-manager distribution, dependency status, update jobs, and historical log backfill.
- [x] 6.3 Add UI states for unavailable actions with safe reasons, redacted secret refs, run online/offline status, build status, update progress, dependency status, and log backfill status.
- [x] 6.4 Preserve the existing platform_web game-operations console style and verify no raw keys, host paths, sockets, DSNs, RCON passwords, or direct run endpoints render in the UI.
## 7. Documentation and Verification
- [x] 7.1 Update platform, run, plugin, and platform_web docs for run generation, client-manager builds, runtime bindings, dependency profiles, live logs, historical logs, and self-update behavior.
- [x] 7.2 Run plugin manifest validation, plugin SDK tests, platform tests, run tests, frontend tests, and `scripts/check-structure.sh`.
- [x] 7.3 Run `openspec validate add-run-distribution-and-client-managers --strict`.
- [x] 7.4 Complete a browser walkthrough for touched server-list and server-detail workflows before marking UI acceptance complete.
- [x] 7.5 Record verification evidence in this task file before completion.
## Verification Evidence
- `cd plugins && npm run validate:manifest`: passed. First sandbox attempt failed with `listen EPERM` on the local `tsx` IPC pipe, then the same command passed with approved escalation.
- `cd plugins && npm run typecheck`: passed.
- `cd plugins && npm test`: passed, 1 file / 17 tests.
- `cd run && go test ./...`: passed.
- `cd platform && go test ./...`: passed.
- `cd platform_web && npm run typecheck`: passed.
- `cd platform_web && npm test`: passed, 13 files / 60 tests.
- `cd platform_web && npm run build`: passed, Vite production build completed.
- `scripts/check-structure.sh`: passed.
- `openspec validate add-run-distribution-and-client-managers --strict`: passed. The CLI printed a PostHog network flush warning after validation, but exited successfully with `Change 'add-run-distribution-and-client-managers' is valid`.
- `LOCAL_DEBUG_PLATFORM_PORT=18189 LOCAL_DEBUG_WEB_PORT=5183 LOCAL_DEBUG_ROOT=/private/tmp/browser-local-debug-acceptance scripts/browser-acceptance.sh`: passed.
- Browser evidence file: `/private/tmp/browser-local-debug-acceptance/browser-acceptance/browser-acceptance-evidence.json`.
- Browser walkthrough evidence covered 首页、服务器管理、服务器管理 / 运行操作菜单、插件市场、用户管理、AI 提供商管理、服务器详情、服务器详情 / 插件控制, plus desktop/mobile checks for black mecha and magical-girl themes.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-12
@@ -0,0 +1,102 @@
## Context
The platform web console already includes the required first-party routes for overview, server management, plugin marketplace, user management, and AI provider management. The current pages are uneven: some are data-backed, some fall back to local demonstration data, and several management surfaces expose create or status actions without complete edit, deletion, retirement, or operational error handling.
This change completes the management console without changing the product scope. Browser code continues to call platform APIs only. AI provider keys remain owned by `platform/`. Run internals, host paths, raw credentials, and direct sockets remain outside `platform_web/` and plugin pages.
## Goals / Non-Goals
**Goals:**
- Make visible management data come from platform APIs in normal operation, with explicit empty/error states when APIs are unavailable.
- Complete user management for editing profile/contact fields, roles, status, and removal or deactivation.
- Complete server management for metadata edits, safe delete/archive, administrator assignment, lifecycle feedback, and detail refresh.
- Complete plugin marketplace behavior for real API data, state actions, detail refresh, and no production demo fallback masking failures.
- Complete AI provider management for correct empty-list behavior, create/update/status/test/model refresh, and deletion or disable-only retirement semantics.
- Keep frontend DTOs, validators, route contracts, and shared view contracts outside page components.
- Preserve the platform_web theme and visual system while making controls dense enough for routine operations.
**Non-Goals:**
- No billing, cloud host sales, provider marketplace, or agent-provider/cloud-provider workflow.
- No direct plugin-to-run access and no browser access to run credentials, host paths, or raw sockets.
- No raw AI key entry or display in `platform_web`; the UI continues to work with secret references only.
- No replacement of the hash router, design system, or global theme architecture.
- No real game process orchestration beyond existing platform-mediated workflows.
## Decisions
### API inventory and removal semantics
- Users: existing `GET/POST /api/v1/users` and `GET/PUT /api/v1/users/{id}` cover list, create, edit, role updates, status updates, and safe removal by deactivation. Hard delete is not exposed; the UI labels removal as `停用` and sends `status=disabled`.
- Server instances: existing list/create/get/lifecycle/admin APIs are extended with `PUT /api/v1/server-instances/{id}` for metadata edits and `DELETE /api/v1/server-instances/{id}` for safe archive. Archive marks the server `deleted`, rejects running/installing states, hides deleted servers from normal lists, and returns them only with `state=deleted`.
- Server administrators: `GET /administrators/candidates`, `POST /administrators`, and `DELETE /administrators/{userId}` remain membership APIs; they never delete user accounts.
- Plugin marketplace: `GET /plugin-marketplace/plugins`, `GET /plugin-marketplace/plugins/{id}`, and `POST /plugin-marketplace/plugins/{id}/state` are the source of list/detail/action state. The page no longer maps `pluginCatalog` into runtime fallback data.
- AI providers: `GET/POST /ai-providers`, `GET/PUT /ai-providers/{id}`, `POST /ai-providers/{id}/status`, `POST /test`, and `GET /models` cover empty lists, save, enable/disable, metadata test, model refresh, and retirement. Retirement is disable-only (`status=disabled`) and raw key material remains rejected by validators.
- Config/logs/run/artifacts/audit: management pages continue using platform-mediated DTOs. Config API failure renders an explicit unavailable state instead of local sample config.
Missing backend support identified during implementation was limited to server instance metadata update and archive/list semantics; these were added with DTO, service, validator, repository, route, documentation, and API tests.
Request/response shapes remain bounded to IDs, logical refs, redacted secret refs, and platform-owned metadata. They do not include raw AI keys, raw host paths, run credentials, direct socket details, or unrestricted plugin execution fields.
### Decision 1: Treat demo data as development-only fixtures
Production pages will not silently replace failed API calls with `pluginCatalog`, `userAccess`, `seedProviders`, or `fallbackConfig`. Development fixtures may remain for isolated tests or explicit local-auth fallback paths, but page status must clearly show API unavailable or empty data.
Alternative considered: keep local fallback data for visual continuity. Rejected because it hides missing backend behavior and makes the console appear functional when data was not loaded.
### Decision 2: Add typed API contracts before page work
Any missing update, delete, retire, archive, or detail-refresh behavior will be represented first in `platform_web/api/types.ts`, `platform_web/api/client.ts`, shared contracts, and schemas. Page components will consume those typed contracts rather than defining request or response shapes inline.
Alternative considered: implement form submit handlers directly against ad hoc endpoints. Rejected because the repository requires API clients, DTOs, contracts, and schemas to stay outside page components.
### Decision 3: Use deactivation or archive when hard deletion is unsafe
Delete-like UI must respect domain safety. Users can be disabled or deleted according to platform rules. AI providers can be disabled or retired if deletion would break references. Server instances can be archived or soft-deleted if a running server or existing history prevents hard deletion. The UI must name the action accurately.
Alternative considered: add one generic delete button everywhere. Rejected because operational resources have different safety and audit requirements.
### Decision 4: Make fallback and failure states auditable
Pages that cannot load API data must show an error or empty state with retry and diagnostic context. Development-only fixtures must be visually isolated and must not enable state-changing actions that imply persistence.
Alternative considered: keep current optimistic local writes after failed API calls. Rejected because it can produce false success for management actions.
### Decision 5: Verify UI workflows in browser after implementation
Because this change touches frontend pages and interactions, completion requires automated tests plus a browser walkthrough. The walkthrough must include the edited pages at desktop and narrow widths and must confirm that no raw secrets, host paths, run credentials, or direct socket values are visible.
Alternative considered: rely only on unit tests. Rejected because these workflows depend on visible controls, responsive layout, and operational feedback states.
## Risks / Trade-offs
- [Risk] Backend APIs may not yet expose every edit/delete operation. Mitigation: implement missing platform DTO, service, repository, handler, and tests in the same change before wiring the UI.
- [Risk] Removing silent fallbacks can make local development feel less populated. Mitigation: keep explicit local debug fixtures behind development-only paths and show clear labels when they are active.
- [Risk] Delete semantics can vary by resource. Mitigation: define resource-specific action labels and confirmation copy, and prefer disable/archive where hard deletion is unsafe.
- [Risk] This change spans several pages. Mitigation: implement one resource workflow at a time with focused tests, then finish with a full browser walkthrough and structure check.
## Migration Plan
1. Inventory current platform API coverage for users, server instances, marketplace plugins, AI providers, config, and maintenance data.
2. Add or extend backend routes and service behavior where required for edit, delete, archive, retire, and detail refresh operations.
3. Update frontend API types, schemas, and shared contracts before page components.
4. Replace silent demo fallbacks with explicit empty/error/local-development states.
5. Implement page-level controls, confirmations, operation feedback, and tests per resource.
6. Run frontend tests/build, relevant backend tests, browser walkthrough, `scripts/check-structure.sh`, and strict OpenSpec validation.
Rollback is contained before downstream changes depend on these workflows: remove the new routes/client methods, restore previous page interactions, and keep read-only views. After users rely on edit/archive actions, rollback should be handled by a new OpenSpec change with data compatibility notes.
## Open Questions
- Resolved: server instance removal is named archive in the UI and implemented as `DELETE` to a `deleted` state so history remains visible by explicit filter.
- Resolved: AI provider removal is disable-only retirement for this implementation.
- Resolved: user removal is deactivation (`disabled`) for this implementation; hard delete is not exposed.
## Verification Evidence
- `go test ./...` from `platform/` passed.
- `cd platform_web && npm run typecheck && npm run test && npm run build` passed.
- `scripts/browser-acceptance.sh` passed, covering users, servers, plugin marketplace, AI providers, server detail, plugin controls, desktop/mobile widths, black-mecha/magical-girl themes, and forbidden-fragment scans. Evidence: `.local-debug/browser-acceptance/browser-acceptance-evidence.json`.
- `scripts/check-structure.sh` passed.
- `openspec validate complete-platform-web-management-workflows --strict` passed. The CLI emitted PostHog telemetry flush network errors after the success line because external network access is unavailable.
@@ -0,0 +1,29 @@
## Why
The platform web console now has the required first-party pages, but several management workflows still depend on local demonstration data or stop at create/status-only interactions. Operators need data-backed editing, deletion, and failure-visible empty states so the console can be used as a real game server operations workspace instead of a partially mocked prototype.
## What Changes
- Replace page-visible demo fallbacks for users, AI providers, plugin marketplace data, and server configuration with explicit API-backed loading, empty, and error states.
- Complete user management with edit, role/profile update, status change, and deletion or deactivation workflows backed by platform APIs.
- Complete server management with metadata edit actions such as rename, ownership/admin changes, safe delete/archive, and clear lifecycle/history feedback without exposing run internals.
- Complete plugin marketplace operations with real empty/error states, safe install/enable/disable handling, plugin detail refresh, and no production reliance on `pluginCatalog` fallback data.
- Complete AI provider management with reliable list-empty behavior, create/update/status/test/model refresh workflows, and deletion or disable-only retirement semantics that preserve secret boundaries.
- Keep the existing platform_web magical game operations visual direction and role-scoped navigation while making pages dense, operational, and browser-verifiable.
## Capabilities
### New Capabilities
- `platform-web-management-completion`: Data-backed platform_web management workflows for users, servers, plugins, AI providers, and related operational states.
### Modified Capabilities
- None. This change builds on existing workflow specs and adds a frontend completion contract rather than modifying archived requirement files.
## Impact
- Affects `platform_web/` API types/client methods, page contracts, schemas, server/user/plugin/AI provider pages, stores, tests, and browser acceptance coverage.
- May require `platform/` DTOs, validators, services, repositories, and HTTP routes where current APIs do not support edit/delete/retire operations.
- May require updates to frontend structure checks if new shared contract/schema directories or rules are introduced.
- Must not add billing, cloud host sales, agent-provider/cloud-provider workflows, unrelated SaaS marketplace features, raw AI key exposure, raw host path exposure, direct run sockets, or plugin access to platform secrets.
@@ -0,0 +1,109 @@
## ADDED Requirements
### Requirement: Management pages use API-backed data states
The platform web management pages SHALL use platform APIs as the source of visible operational data and SHALL render explicit loading, empty, error, or development-fixture states instead of silently substituting production data with local examples.
#### Scenario: API returns an empty list
- **WHEN** a management page API returns an empty list for users, servers, plugins, AI providers, logs, audit events, or run endpoints
- **THEN** the page MUST render an empty state that reflects the empty API response and MUST NOT keep previously seeded demonstration rows visible
#### Scenario: API request fails
- **WHEN** a management page API request fails in normal operation
- **THEN** the page MUST render an error state with retry affordance or diagnostic context and MUST NOT enable persistence-looking actions against local fallback data
#### Scenario: Development fixture is active
- **WHEN** an explicit development fixture or local-auth fallback is active
- **THEN** the page MUST label the data as local development data and MUST disable or clearly reject state-changing actions that cannot be persisted
### Requirement: Management list pages preserve full-width work surfaces
The platform web management pages SHALL keep list, grid, and table views as full-width work surfaces and SHALL put create, edit, and detail workflows in modal, drawer, or detail-route surfaces instead of permanent side panes or inline split forms.
#### Scenario: Operator opens create, edit, or detail workflow
- **WHEN** an operator opens create, edit, or detail workflows on users, plugin marketplace, AI providers, servers, or similar management list pages
- **THEN** the page MUST keep the underlying list, grid, or table full-width and MUST render the workflow in a modal, drawer, or detail route without a permanent right-side form/detail pane
### Requirement: User management supports full account maintenance
The user management page SHALL allow authorized platform administrators to create users, edit user identity/contact fields, update roles, update status, and remove or deactivate users through platform APIs.
#### Scenario: Administrator edits user fields
- **WHEN** a platform administrator edits a user's display name, email, phone, QQ, contact note, roles, or status
- **THEN** the frontend MUST submit a named API request, render success or failure feedback, and update the list from the persisted response
#### Scenario: Administrator removes or deactivates a user
- **WHEN** a platform administrator confirms a user removal or deactivation action
- **THEN** the platform MUST enforce the resource safety rule and the frontend MUST render the resulting removed, disabled, or rejected state without pretending a local write succeeded
#### Scenario: Non-admin reaches user management
- **WHEN** a user without `users.manage` reaches the user management route directly
- **THEN** the page MUST avoid rendering account maintenance controls and MUST return or explain the authorized workspace state
### Requirement: Server management supports metadata edit and safe removal
The server management workspace SHALL allow authorized users to create server instances, edit server metadata, manage server administrators, start and stop eligible instances, and archive or delete safe instances through platform-mediated APIs.
#### Scenario: Operator edits server metadata
- **WHEN** an authorized operator updates a server name, ownership-visible metadata, or other editable server fields
- **THEN** the frontend MUST submit a typed platform API request and render the persisted server instance response
#### Scenario: Operator archives or deletes a server
- **WHEN** an authorized operator confirms archive or delete for a server instance
- **THEN** the platform MUST reject unsafe states such as running instances unless the chosen operation is explicitly allowed, and the frontend MUST render the accepted or rejected result with diagnostic context
#### Scenario: Server detail manages administrators
- **WHEN** a server owner adds or removes server administrators from the server detail page
- **THEN** the frontend MUST use platform administrator membership APIs and refresh candidate and assigned member state after the operation
### Requirement: Plugin marketplace avoids production demo fallbacks
The plugin marketplace SHALL render platform marketplace data and state actions from platform APIs and SHALL NOT rely on `pluginCatalog` fallback data in production behavior.
#### Scenario: Marketplace API is unavailable
- **WHEN** the marketplace list or detail API request fails
- **THEN** the marketplace page MUST show an error or explicitly labeled development fixture state and MUST NOT present local catalog rows as persisted marketplace data
#### Scenario: Plugin state action is submitted
- **WHEN** an operator installs, enables, or disables a plugin
- **THEN** the frontend MUST call the platform marketplace state API, display the operation result, and update the selected plugin detail from the persisted response
#### Scenario: Plugin detail is refreshed
- **WHEN** an operator selects or refreshes a plugin detail
- **THEN** the frontend MUST prefer the platform detail API response and MUST render validation, permission, lifecycle, page, bridge, and AI purpose metadata without exposing secrets or run internals
### Requirement: AI provider management handles empty data and retirement safely
The AI provider management page SHALL handle empty API lists correctly and SHALL support create, update, enable/disable, test, model refresh, and deletion or retirement semantics without exposing raw AI key material.
#### Scenario: AI provider API returns zero providers
- **WHEN** the AI provider list API succeeds with zero providers
- **THEN** the page MUST render an empty state or creation form and MUST NOT keep seed providers visible
#### Scenario: Provider is saved
- **WHEN** an operator creates or updates an AI provider
- **THEN** the frontend MUST submit a named API request using secret references only and MUST render the redacted provider response
#### Scenario: Provider is retired or deleted
- **WHEN** an operator confirms provider deletion or retirement
- **THEN** the platform MUST enforce reference safety and the frontend MUST remove, disable, or mark the provider according to the persisted response
#### Scenario: Provider action fails
- **WHEN** provider save, status, test, model refresh, delete, or retire action fails
- **THEN** the frontend MUST display failure feedback and MUST NOT mutate local state as if the action succeeded
### Requirement: Management completion preserves security boundaries
The completed management workflows SHALL NOT expose raw AI keys, raw host paths, run credentials, direct socket addresses, or unrestricted plugin execution controls to `platform_web` or plugin pages.
#### Scenario: Page renders operational data
- **WHEN** any completed management page renders users, servers, plugins, AI providers, logs, audit events, artifacts, jobs, or run endpoints
- **THEN** the rendered data MUST omit raw AI keys, raw host paths, run credentials, and direct socket details
#### Scenario: Plugin control action is rendered
- **WHEN** plugin controls or bridge actions are rendered for a server
- **THEN** the controls MUST be derived from platform-approved plugin metadata and MUST dispatch through platform APIs rather than direct run or host access
### Requirement: Management completion is verified end to end
The change SHALL include automated tests, structure validation, strict OpenSpec validation, and browser walkthrough evidence for the completed management workflows.
#### Scenario: Verification commands run
- **WHEN** the implementation is complete
- **THEN** relevant backend tests, `cd platform_web && npm run typecheck && npm run test && npm run build`, `scripts/check-structure.sh`, and `openspec validate complete-platform-web-management-workflows --strict` MUST pass or have documented blockers
#### Scenario: Browser walkthrough covers edited pages
- **WHEN** frontend management workflows are claimed complete
- **THEN** a browser walkthrough MUST verify users, servers, plugin marketplace, AI providers, and related error/empty states at desktop and narrow widths
@@ -0,0 +1,65 @@
## 1. API and Safety Inventory
- [x] 1.1 Inventory current platform APIs for users, server instances, server administrators, plugin marketplace, AI providers, config, logs, run endpoints, and audit events.
- [x] 1.2 Decide and document resource-specific removal semantics for users, server instances, and AI providers: delete, disable, archive, or retire.
- [x] 1.3 Identify missing backend DTOs, validators, repository methods, service methods, and HTTP routes required by the frontend completion workflows.
- [x] 1.4 Confirm no planned request or response shape includes raw AI keys, raw host paths, run credentials, direct socket details, or unrestricted plugin execution fields.
## 2. Platform API Support
- [x] 2.1 Add or extend user management APIs for editing identity/contact fields, roles, status, and delete/deactivate behavior.
- [x] 2.2 Add or extend server instance APIs for metadata edits and safe archive/delete behavior while preserving lifecycle validation.
- [x] 2.3 Add or extend AI provider APIs for empty list correctness and delete/retire behavior with secret-reference-only validation.
- [x] 2.4 Add backend tests for accepted and rejected edit/delete/archive/retire workflows and stable JSON errors.
- [x] 2.5 Update platform route/API documentation for newly added management actions.
## 3. Frontend Contracts and Schemas
- [x] 3.1 Add frontend API DTO types and client methods for all new user, server, plugin, and AI provider management actions.
- [x] 3.2 Add shared frontend contracts for edit forms, removal confirmations, operation result state, and development-fixture state outside page components.
- [x] 3.3 Add or update frontend schemas for user edit, server metadata edit, server removal, AI provider save, and AI provider retirement requests.
- [x] 3.4 Remove unused static shell demo constants or isolate them as explicit test/development fixtures.
## 4. User Management Completion
- [x] 4.1 Replace silent `fallbackUsers` display with API-backed loading, empty, error, and explicitly labeled local-development states.
- [x] 4.2 Add existing-user edit controls for profile/contact fields, roles, and status using typed API requests.
- [x] 4.3 Add user delete/deactivate confirmation flow with persisted result feedback and rejection diagnostics.
- [x] 4.4 Add tests for user empty state, edit success, edit failure, status update, and delete/deactivate behavior.
## 5. Server Management Completion
- [x] 5.1 Add server list or detail controls for editable server metadata such as display name and allowed ownership-visible fields.
- [x] 5.2 Add safe server archive/delete flow with state-aware confirmation and platform rejection feedback.
- [x] 5.3 Ensure server administrator add/remove flows refresh assigned administrators and candidates after each operation.
- [x] 5.4 Replace server config fallback behavior with explicit API unavailable state or clearly labeled local-development fixture state.
- [x] 5.5 Add tests for server metadata edit, archive/delete rejection, administrator refresh, and config unavailable state.
## 6. Plugin Marketplace Completion
- [x] 6.1 Remove production reliance on `pluginCatalog` fallback data from marketplace list and detail rendering.
- [x] 6.2 Render marketplace API empty and error states with retry and diagnostic context.
- [x] 6.3 Ensure install, enable, and disable actions update list and detail state only from persisted platform responses.
- [x] 6.4 Add tests for marketplace API failure, empty list, detail refresh, disabled fixture actions, and state action feedback.
## 7. AI Provider Completion
- [x] 7.1 Fix zero-provider API responses so seed providers are not kept visible after a successful empty list.
- [x] 7.2 Remove optimistic local success for failed save, status, test, model refresh, and delete/retire actions.
- [x] 7.3 Add delete or retire action UI with confirmation, persisted response handling, and reference-safety rejection feedback.
- [x] 7.4 Add tests for empty provider list, create/update failure, status failure, model refresh failure, and delete/retire behavior.
## 8. Verification
- [x] 8.1 Run relevant backend tests from `platform/` and record evidence.
- [x] 8.2 Run `cd platform_web && npm run typecheck && npm run test && npm run build` and record evidence.
- [x] 8.3 Run a browser walkthrough covering users, servers, plugin marketplace, AI providers, and empty/error states at desktop and narrow widths.
- [x] 8.4 Run forbidden-fragment checks for raw AI keys, raw host paths, run credentials, and direct socket details in rendered management pages.
- [x] 8.5 Run `scripts/check-structure.sh` and record evidence.
- [x] 8.6 Run `openspec validate complete-platform-web-management-workflows --strict` and record evidence.
## 9. Management Layout Corrections
- [x] 9.1 Replace permanent inline create/edit/detail panes on AI provider, user, and plugin marketplace list pages with modal workflows while preserving full-width list surfaces.
- [x] 9.2 Document the ban on permanent right-side or inline split management panes in platform_web Markdown guidance.
- [x] 9.3 Verify AI provider create/edit, user create/edit, and plugin detail workflows in a browser after the modal conversion.
@@ -40,10 +40,18 @@ This change should stay inside platform_web interaction and visual polish. It mu
Lifecycle actions, destructive confirmations, logs, diffs, config review, operation results, warnings, and AI recommendations must remain text-readable, traceable, and not color-only. Decorative theme effects must stay behind operational surfaces and respect reduced motion.
5. Use browser walkthroughs for acceptance, not screenshots alone.
5. Demote low-value counters near management headers.
Tiny counts such as installed plugin count, user count, role count, pending review count, provider count, enabled count, and model count are useful as context but should not become primary framed KPI cards. Management pages should keep scarce vertical space for the actual work surface: search/filter bars, plugin catalog, user table, and provider table.
6. Use browser walkthroughs for acceptance, not screenshots alone.
Completion requires exercising the actual routes and workflows in a browser at representative desktop and mobile widths. Screenshots can help debugging, but accepted evidence should focus on route behavior, visible controls, responsive layout, and absence of overlap or sensitive/fallback content.
7. Prefer human-operable flows over raw DTO forms.
Management pages should expose the same platform-backed actions, but the UI should bundle them into understandable operator flows: one status-change path per user, readable AI provider row actions, provider setup presets and secret-reference help, and maintenance triage entry points that connect failed jobs or stale endpoints to the next useful page. These additions remain presentation/workflow polish and do not add new authorization, run, plugin, or provider semantics.
## Risks / Trade-offs
- Visual polish can drift into scope expansion -> Keep tasks limited to platform_web interaction and theme presentation; do not change platform/run/plugin semantics.
@@ -5,6 +5,7 @@ The console now has real API-backed coverage and automated browser acceptance, b
## What Changes
- Define accepted interaction/design criteria for the required first-party areas: 首页、服务器管理、插件市场、用户管理、AI 提供商管理.
- Compress low-value management page summary counts into compact status context so primary list/table surfaces keep the scarce first-screen space.
- Define server detail workflow polish for lifecycle controls, logs, config, plugin controls, AI assistant, and operation history.
- Require responsive desktop/mobile walkthrough coverage and no visible overlap, clipped text, unreadable panels, or inaccessible control states.
- Require the polish to preserve the existing black mecha default theme, magical-girl alternate theme, translucent game-operations surfaces, grouped navigation, and shared theme primitives.
@@ -23,6 +23,10 @@ The platform_web console SHALL provide polished, scannable, API-backed interacti
- **WHEN** an operator opens AI 提供商管理
- **THEN** the route MUST present provider identity, connection status, relay mode, model/default-model information, and redacted key references without exposing raw keys or making status dependent on color alone
#### Scenario: Management page counters stay secondary
- **WHEN** an operator opens 插件市场、用户管理, or AI 提供商管理
- **THEN** small summary counts such as installed plugins, bridge actions, validation failures, users, roles, pending reviews, providers, enabled providers, and models MUST render as compact contextual status instead of large framed KPI cards that displace the primary list, grid, table, search, or filter work surface
### Requirement: Server detail workflows are polished without direct run access
The platform_web server detail route SHALL provide polished workflow surfaces for lifecycle, logs, config, plugin controls, AI assistant, and operation history while preserving platform-mediated boundaries.
@@ -43,6 +43,21 @@
- [x] 6.4 If structural theme rules or shared style contracts change, update `platform_web/theme/README.md` and any relevant tests in the same change.
- [x] 6.5 Update `openspec/changes/architecture-delivery-stream/delivery-plan.md` and `openspec/changes/architecture-delivery-stream/NEXT_CHANGE.md` after implementation evidence exists.
## 7. Management Header Density Correction
- [x] 7.1 Replace large framed management summary KPI cards in 插件市场、用户管理, and AI 提供商管理 with compact contextual status chips.
- [x] 7.2 Add regression tests proving those management headers render `page-summary-chip` instead of `metric-card`.
- [x] 7.3 Run focused frontend tests, `scripts/check-structure.sh`, and `openspec validate polish-platform-interaction-design --strict`; record evidence.
## 8. Human Workflow Polish Follow-up
- [x] 8.1 Replace duplicate 用户管理 status/deactivation buttons with one status selector flow and explicit confirmation when disabling access.
- [x] 8.2 Add user invitation, review, server-scope, and role-impact guidance without adding new backend authorization semantics.
- [x] 8.3 Replace AI provider icon-only row actions with readable action labels and a compact "more" menu for lower-frequency enable/retire actions.
- [x] 8.4 Add AI provider setup guidance: presets, secret-reference help, save-before validation, saved-configuration testing, and model discovery fill-in.
- [x] 8.5 Add 系统维护 triage entry points for endpoint heartbeat/capacity, failed jobs, and related server/log navigation links.
- [x] 8.6 Run focused frontend tests and typecheck; use the existing 5173 browser instance to spot-check the changed pages.
## Evidence
- `platform_web/pages/UsersPage.tsx`: added explicit loading, API fallback error, empty-state, and accessible row action labels for 用户管理.
@@ -51,7 +66,14 @@
- `platform_web/pages/PluginsPage.tsx`: polished plugin detail framing and action strip behavior.
- `platform_web/theme/base.css`: hardened shared action strips, server toolbars, catalog cards, plugin detail panels, result strips, responsive grids, and table/workspace min-width behavior.
- `platform_web/acceptance/browser-acceptance.mjs`: expanded browser acceptance to record desktop/mobile walkthroughs for black mecha and magical-girl themes, route marker checks, visible-layout checks, API-backed route proof, plugin controls, and operation-history proof.
- Header density correction evidence: `platform_web/components/PageFrame.tsx` and `platform_web/pages/AiProvidersPage.tsx` now render management summary counts as `page-summary-chip`; `platform_web/pages/PluginsPage.test.tsx`, `platform_web/pages/UsersPage.test.tsx`, and `platform_web/pages/AiProvidersPage.test.tsx` assert those headers no longer render `metric-card`.
- Focused frontend evidence: `cd platform_web && npm test -- PluginsPage.test.tsx UsersPage.test.tsx AiProvidersPage.test.tsx`, `cd platform_web && npm run typecheck`, and `cd platform_web && npm run build` passed for the header density correction.
- Browser evidence: `LOCAL_DEBUG_PLATFORM_PORT=18189 LOCAL_DEBUG_WEB_PORT=5183 LOCAL_DEBUG_ROOT=/private/tmp/browser-local-debug-acceptance scripts/browser-acceptance.sh` passed; evidence file `/private/tmp/browser-local-debug-acceptance/browser-acceptance/browser-acceptance-evidence.json` records 7 required routes plus 4 walkthrough scenarios: desktop/mobile black mecha and desktop/mobile magical-girl.
- Frontend evidence: `cd platform_web && npm run typecheck`, `cd platform_web && npm test` (11 files / 49 tests), and `cd platform_web && npm run build` passed.
- Structure evidence: `scripts/check-structure.sh` passed.
- OpenSpec evidence: `openspec validate polish-platform-interaction-design --strict` passed.
- Human workflow polish evidence: `platform_web/pages/UsersPage.tsx` now uses one status selector/apply path, keeps disable confirmation, renames create flow to 邀请用户, and shows invite/review/server-scope/role-impact guidance.
- AI provider workflow evidence: `platform_web/pages/AiProvidersPage.tsx` now shows row actions as 测试 / 模型 / 编辑 / 更多, moves enable/retire into the more menu, adds provider presets, secret-reference help, 保存前检查, saved-configuration testing, and saved-model discovery fill-in.
- Maintenance triage evidence: `platform_web/pages/MaintenancePage.tsx` now loads endpoints, jobs, servers, and audit events to show node heartbeat/capacity detail, recent failed jobs, retry dispatch, related server links, and log-chain entry copy.
- Human workflow verification: `cd platform_web && npm test -- UsersPage.test.tsx AiProvidersPage.test.tsx ConsolePages.test.tsx`, `cd platform_web && npm run typecheck`, and `cd platform_web && npm run build` passed. `scripts/check-structure.sh` passed. `openspec validate polish-platform-interaction-design --strict` passed; only PostHog telemetry flushing failed due restricted network after validation succeeded.
- Browser spot-check evidence: existing `http://127.0.0.1:5173` was opened and logged in with the local test operator. `#/aiProviders` showed readable row actions and edit dialog guidance with no clipped target buttons and no `api.example.test`; `#/users` showed 邀请用户, 审核申请, 绑定服务器范围, 角色影响, 应用状态, no duplicate “停用用户” label, and no clipped target buttons; `#/maintenance` showed 系统维护, 节点详情, 最近失败任务, heartbeat/status context, and the follow-up commit adds visible 维护排障入口 / 查看相关服务器 / 查看日志链路 copy for empty-data states.