功能修改

This commit is contained in:
npc0-hue
2026-07-20 16:42:33 +08:00
parent 48b8ad8d6c
commit a0e69417db
224 changed files with 22015 additions and 884 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-18
@@ -0,0 +1,92 @@
## Context
The console already has five required first-party areas, typed Platform API clients, role-scoped routes, long-running job polling, operation tracking, and the black-mecha/magical-girl theme system. The remaining problem is cohesion and truthfulness: the overview hides some API failures as empty collections, page mutations use inconsistent busy/confirm/retry behavior, and operators lack a compact cross-page view of active and failed work.
This change stays inside `platform_web/` and consumes existing Platform API projections. It does not make the browser a source of truth for jobs, resource state, permissions, or secrets.
## Goals / Non-Goals
**Goals:**
- Make loading, empty, unavailable, stale, active, succeeded, and failed states visually and semantically distinct.
- Give operators an actionable overview of server health, Run endpoint safe status, active/failed jobs, AI provider availability, resource pressure, and recent audit signals.
- Standardize mutation behavior around permission gating, confirmation where state is disruptive, action-level busy state, persisted response handling, and retry after failure.
- Keep first-party list pages full-width and dense while retaining modal/detail-route workflows.
- Preserve the theme and responsive contracts at desktop and 390px.
- Recover narrow-screen vertical space by moving the existing ordered text navigation into an off-canvas sidebar with a small theme-aware left-edge handle and bounded swipe gesture.
**Non-Goals:**
- No new Platform or Run endpoint, persistence model, permission, or job state machine.
- No raw secret/key/token/path/PID/socket/credential/DSN/RCON projection.
- No billing, cloud hosting sales, provider marketplace, fleet orchestration, arbitrary shell, or direct browser-to-Run channel.
- No route, sidebar order, theme palette, or global particle architecture replacement.
## Decisions
### Decision 1: Aggregate existing safe APIs in the browser without inventing platform health
The overview will fetch server instances, safe Run endpoint projections, jobs, metrics, platform usage, AI providers, and audit events as independent modules. Each module keeps its own state and refresh timestamp. Failed modules remain visibly unavailable and are excluded from healthy/empty conclusions.
Alternative considered: add one new dashboard API. Rejected because current APIs already provide the bounded projections needed, and this change does not need a new backend contract.
### Decision 2: Derive operational summaries in shared pure contracts
Job buckets, attention signals, server list sorting/filtering, provider summaries, and safe operation labels will live outside page components. Pages render derived view contracts and tests can lock classification without constructing full page trees.
Alternative considered: calculate every summary inline. Rejected because the same terminal/active/failure classification is needed by the overview, server page, and global operation tray.
### Decision 3: Platform responses remain authoritative
Mutations only update resource state from a successful Platform response or a subsequent refresh. Long-running operations use real job IDs and job polling. A rejected request keeps the previous resource state, preserves the failure message, and exposes retry where the same request remains valid.
Alternative considered: optimistic state transitions. Rejected because plugin/provider/server operations can be rejected by ownership, lifecycle, dependency, or reference constraints.
### Decision 4: Disruptive state changes use a shared confirmation contract
Plugin install/enable/disable, AI provider enable/disable/retire, user deactivation, and server destructive actions require resource-specific confirmation. Dialogs close on Escape or cancellation, preserve focus behavior, and disable duplicate submission while busy.
Alternative considered: confirm only destructive deletes. Rejected because enable/disable and install actions can interrupt running capabilities or create durable work.
### Decision 5: Capabilities control commands, routes control discovery
The existing route capability mapping remains the navigation authority. Within an allowed page, mutation controls check the matching session capability and render a clear read-only state when missing. The browser does not elevate access and still handles Platform 401/403 as authoritative rejection.
Alternative considered: hide every unauthorized control. Rejected because operators benefit from understanding why a page is read-only; safety-critical commands remain unavailable.
### Decision 6: Extend the existing theme system with shared operational primitives
New pulse rows, module status headers, compact job rows, and the operation tray use shared classes appended to `theme/base.css`, `var(...)` tokens, existing radius limits, and theme-specific material variables. Global decoration remains exclusively in `MagicalParticleLayer`.
Alternative considered: page-local cards and effects. Rejected because they would fragment theme switching and violate the repository style contract.
### Decision 7: Use an off-canvas text sidebar on narrow screens
At 760px and below, the sidebar leaves normal document flow and stays closed until the operator activates the left-edge handle or completes a rightward swipe that begins at the viewport edge. The drawer preserves the desktop route order, icons, Chinese labels, account access, and session operations; backdrop click, Escape, route selection, and a leftward drawer swipe close it.
Alternative considered: keep the horizontal icon rail and account strip above every page. Rejected because it consumes scarce vertical space, hides route labels, and makes repeated mobile operations slower to scan.
## Risks / Trade-offs
- [Risk] Independent overview requests can complete out of order. Mitigation: refresh callbacks update only their module and use explicit loading/ready/error states.
- [Risk] More status rows can overload narrow layouts. Mitigation: collapse multi-column regions to a single ordered flow at 390px and keep command rows bounded.
- [Risk] Horizontal content gestures can open navigation accidentally. Mitigation: require the opening swipe to start within the left 28px edge and travel at least 56px, while drawer-closing swipes use the inverse threshold.
- [Risk] In-session operation history is not durable. Mitigation: label it as current-session request feedback; durable job and audit history continues to come from Platform APIs.
- [Risk] Existing item 8 edits overlap `base.css` and API types. Mitigation: reuse its current worktree state, append narrowly scoped classes, and avoid reverting or rewriting lifecycle code.
- [Risk] Action confirmation can add friction. Mitigation: require it only for persistent or disruptive operations; refresh and navigation remain immediate.
## Migration Plan
1. Add shared derived contracts and tests.
2. Add shared operation tray and accessible dialog behavior.
3. Update each first-party page while keeping existing API methods and routes.
4. Add shared theme styles and responsive rules.
5. Run frontend tests/typecheck/build, structure validation, strict OpenSpec validation, and browser acceptance in both themes and at 390px.
Rollback is frontend-only: remove the new shared components/contracts and restore the previous page render paths. No persisted data migration is required.
## Open Questions
- Resolved: this change uses existing APIs and does not add a dashboard endpoint.
- Resolved: the operation tray is session-scoped feedback; Platform jobs and audit events remain durable truth.
- Resolved: development fixtures may remain in tests, but normal page rendering does not silently substitute them for failed APIs.
@@ -0,0 +1,31 @@
## Why
The first-party console has real management APIs and complete resource workflows, but operators still have to infer platform health across pages, some API failures are rendered as empty success states, and several state-changing actions lack a consistent confirm, progress, and recovery cycle. The next console iteration must turn the existing pages into a cohesive operations workspace without weakening permission or secret boundaries.
## What Changes
- Add a permission-aware operations overview that distinguishes live, delayed, failed, empty, and unavailable API modules and surfaces active or failed jobs, endpoint health, resource pressure, and actionable navigation.
- Deepen server management with explicit telemetry availability, job-state summaries, deterministic refresh behavior, and recovery-oriented feedback while retaining real job polling for long-running work.
- Deepen plugin marketplace operations with permission gating, confirmation for state changes, persisted-response refresh, action progress, and retryable failures.
- Remove normal-page user fixture fallbacks and add API-backed search, role/status filtering, operational summaries, retry, and mutation feedback.
- Deepen AI provider management with retryable loading, action-level busy states, confirmation for enable/disable/retire operations, saved-response refresh, and safe configuration presence rather than raw key disclosure.
- Add a compact global operation tray for in-session API mutations, including pending, succeeded, and failed records with diagnostic context and page-safe target labels.
- Replace the narrow-screen top navigation stack with a theme-aware off-canvas sidebar that keeps Chinese labels visible, opens from a bounded left-edge control or rightward edge swipe, and closes without consuming page height.
- Preserve the existing black-mecha and magical-girl crystal-moonlight theme system, shared surfaces, route order, and `MagicalParticleLayer` ownership.
- Keep browser and plugin projections free of raw keys, tokens, secret values, host paths, PIDs, sockets, credentials, DSNs, RCON data, and direct Run endpoints.
## Capabilities
### New Capabilities
- `platform-operations-console-enrichment`: Permission-aware, API-backed operations views and mutation recovery workflows across overview, servers, plugins, users, and AI providers.
### Modified Capabilities
None.
## Impact
- Affects `platform_web/` contracts, shared components, operation tracking, first-party pages, theme styles, tests, and browser acceptance coverage.
- Uses existing Platform APIs for server instances, Run endpoint safe projections, jobs, metrics, audit events, plugins, users, and AI providers; no new direct Run or secret-bearing browser contract is introduced.
- Does not add billing, cloud host sales, provider marketplaces, arbitrary remote execution, or unrelated SaaS features.
@@ -0,0 +1,124 @@
## ADDED Requirements
### Requirement: Permission-aware operations overview
The console SHALL provide an overview that derives server, Run endpoint, job, resource, AI provider, and audit summaries from Platform API responses permitted for the active session.
#### Scenario: Operator opens overview with available APIs
- **WHEN** the active session can read the overview and the required Platform APIs return data
- **THEN** the console shows real counts, resource measurements, active and failed job summaries, endpoint health, and actionable signals derived from those responses
#### Scenario: Session lacks a management capability
- **WHEN** a session can view an operational resource but lacks the capability required to mutate it
- **THEN** the console presents a read-only explanation and does not dispatch the mutation
### Requirement: Independent module truth and recovery
Each overview and management data module MUST distinguish loading, ready-empty, ready-data, and unavailable states, and MUST provide scoped retry without treating an API failure as an empty or healthy result.
#### Scenario: Audit API fails while core overview succeeds
- **WHEN** server and job APIs succeed but the audit API fails
- **THEN** core health remains visible, audit signals are marked unavailable, and the page does not claim that there are no recent audit signals
#### Scenario: Failed module is retried
- **WHEN** an operator retries an unavailable module and its API succeeds
- **THEN** only that module transitions to ready data and its refresh timestamp is updated
### Requirement: Real job and mutation progress
Long-running work MUST use Platform job identifiers and job states, while immediate mutations MUST remain pending until the Platform response returns and MUST never use timers or optimistic local success.
#### Scenario: Long-running server operation is queued
- **WHEN** a server operation returns a job identifier
- **THEN** the console polls the Platform job projection and shows queued, claimed, running, retrying, terminal success, or terminal failure from that projection
#### Scenario: Mutation is rejected
- **WHEN** the Platform rejects a plugin, user, server, or AI provider mutation
- **THEN** the previous resource state remains visible and the console shows the rejection with a retry or corrective action when applicable
### Requirement: Confirmed disruptive operations
Persistent or disruptive resource state changes MUST require resource-specific confirmation and MUST prevent duplicate submission while a request is pending.
#### Scenario: Plugin state change is confirmed
- **WHEN** an authorized operator chooses install, enable, or disable and confirms the named plugin action
- **THEN** the console dispatches one Platform request, disables duplicate confirmation, and refreshes state from the persisted response
#### Scenario: Confirmation is cancelled
- **WHEN** an operator cancels a confirmation or presses Escape before submission
- **THEN** no mutation is dispatched and the current resource state is preserved
### Requirement: Server operations workspace
Server management SHALL expose API telemetry availability, deterministic search/filter/sort, active and failed job counts, and recovery-oriented navigation without covering or reflowing server-card operational data.
#### Scenario: Metrics are unavailable
- **WHEN** the server list succeeds but metrics loading fails
- **THEN** server cards remain available, metrics are labeled unavailable rather than zero, and a scoped metrics retry is offered
#### Scenario: Server has active or failed jobs
- **WHEN** Platform jobs reference a visible server
- **THEN** the server working surface shows the real active or failed job count and lets the operator open the server detail or job progress workflow
### Requirement: Plugin marketplace operations
The plugin marketplace SHALL use Platform list/detail/state responses, permission-gated commands, confirmation, action progress, and failure recovery without production fallback data.
#### Scenario: Plugin state response succeeds
- **WHEN** the Platform accepts a confirmed plugin state action
- **THEN** list and detail views update from the returned or refreshed Platform plugin state and the action result is traceable
#### Scenario: Plugin detail refresh fails
- **WHEN** the selected plugin summary exists but its detail API fails
- **THEN** the summary remains visible, detail is marked unavailable, and the operator can retry detail loading without reloading the page
### Requirement: User management operations
User management SHALL render only Platform API data in normal operation and SHALL provide search, role/status filtering, create/edit/status/deactivate feedback, and API-scoped retry.
#### Scenario: User API fails in development
- **WHEN** the normal user list API fails in a development build
- **THEN** the page shows an unavailable state and does not replace the result with actionable sample users
#### Scenario: User filters are applied
- **WHEN** an authorized operator enters a query or selects role/status filters
- **THEN** the full-width user working surface shows only matching Platform users and keeps create/edit flows in dialogs
### Requirement: AI provider operations
AI provider management SHALL provide scoped list retry, action-level busy states, confirmed status/retirement changes, persisted-response refresh, and safe key configuration presence.
#### Scenario: Provider load is retried
- **WHEN** the provider list fails and the operator retries
- **THEN** the page calls the provider list API again without a full browser reload and renders the returned state
#### Scenario: Provider status action is pending
- **WHEN** an authorized operator confirms enable, disable, or retire
- **THEN** only that provider action is disabled, duplicate submission is prevented, and success is shown only after a Platform response
### Requirement: Session operation tray
The console SHALL expose a compact, theme-aware tray for current-session mutation records while clearly distinguishing it from durable Platform job and audit history.
#### Scenario: Operation fails
- **WHEN** a tracked mutation fails
- **THEN** the tray shows the intent, safe target label, failure reason, and diagnostic identifier without exposing forbidden values
#### Scenario: No session operations exist
- **WHEN** no mutation has been attempted in the current session
- **THEN** the tray remains compact and communicates that durable job and audit history is available on the relevant operational pages
### Requirement: Theme, responsive, and secret safety
All new operations surfaces MUST use existing theme tokens and shared styles, MUST remain coherent in black-mecha and magical-girl themes at desktop and 390px, and MUST not render raw keys, tokens, secret values, host paths, PIDs, sockets, credentials, DSNs, RCON data, or direct Run endpoints.
#### Scenario: Theme changes
- **WHEN** an operator switches between black-mecha and magical-girl themes
- **THEN** overview modules, lists, confirmations, progress rows, and the operation tray update atomically through existing theme variables without page-local global decoration
#### Scenario: Narrow viewport renders operations surfaces
- **WHEN** the console is rendered at 390px width
- **THEN** controls and text remain within their containers, full-width working surfaces collapse deliberately, and no operational status or action is obscured
#### Scenario: Narrow viewport navigation stays out of page flow
- **WHEN** the console is rendered at 390px width with navigation closed
- **THEN** the sidebar, account strip, and icon rail do not consume page height, and a small theme-aware left-edge menu control remains available
#### Scenario: Operator opens and closes narrow navigation
- **WHEN** the operator activates the left-edge control or swipes right from within 28px of the viewport edge
- **THEN** an off-canvas vertical menu opens with icons and readable Chinese route labels in the existing order
- **AND** Escape, backdrop activation, route selection, or a leftward drawer swipe closes the menu
#### Scenario: Rendered output is scanned for forbidden fragments
- **WHEN** first-party pages are rendered with API-backed fixtures during verification
- **THEN** forbidden raw secret, path, process, socket, credential, DSN, RCON, and direct Run endpoint fragments are absent
@@ -0,0 +1,69 @@
## 1. Shared Operations Contracts
- [x] 1.1 Add shared frontend view contracts for module availability, job buckets, attention signals, and safe operation targets outside page components.
- [x] 1.2 Add pure derivation helpers for active/failed jobs, server attention sorting, and overview module summaries.
- [x] 1.3 Add focused tests for job classification, unavailable-module handling, deterministic ordering, and forbidden-field omission.
## 2. Shared Operations UI
- [x] 2.1 Add a compact theme-aware current-session operation tray with pending, succeeded, failed, and empty states.
- [x] 2.2 Pass the operation tracker through the shell and keep durable Platform job/audit history clearly distinguished from session feedback.
- [x] 2.3 Add Escape handling, duplicate-submit protection, and accessible labels to shared management and confirmation dialogs.
## 3. Operations Overview
- [x] 3.1 Refactor overview API modules so metrics, usage, providers, and audit events preserve independent loading, ready, empty, and unavailable states.
- [x] 3.2 Add actionable endpoint/job/resource/provider status modules and scoped retry/refresh timestamps using only safe Platform projections.
- [x] 3.3 Add overview tests covering partial API failure, active/failed jobs, actionable navigation, and read-only session behavior.
## 4. Server Management
- [x] 4.1 Add explicit metrics availability/retry and deterministic status/job sorting to the full-width server working surface.
- [x] 4.2 Add real active/failed job summaries and recovery navigation without reflowing cards or simulating terminal success.
- [x] 4.3 Add tests for metrics failure, job summaries, sorting, and permission-aware create/action controls.
## 5. Plugin Marketplace
- [x] 5.1 Add permission-gated confirmed install/enable/disable actions with per-action busy state and persisted-response refresh.
- [x] 5.2 Add scoped plugin detail retry that preserves the list summary when detail loading fails.
- [x] 5.3 Add tests for confirmation cancellation, duplicate-submit prevention, state failure recovery, and detail retry.
## 6. User Management
- [x] 6.1 Remove normal-page development user fallback substitution and render API failure with scoped retry.
- [x] 6.2 Add API-backed search, role/status filters, operational summaries, and clear-filter behavior to the full-width user list.
- [x] 6.3 Add tests for development API failure, filtering, mutation failure preservation, and platform-admin gating.
## 7. AI Provider Management
- [x] 7.1 Replace full-page reload retry with scoped provider loading and preserve explicit empty versus unavailable states.
- [x] 7.2 Add confirmed enable/disable/retire actions, provider-scoped busy state, persisted-response refresh, and safe key-presence copy.
- [x] 7.3 Add tests for scoped retry, confirmation cancellation, pending duplicate prevention, and failed action recovery.
## 8. Theme and Responsive Integration
- [x] 8.1 Add shared theme styles for operations modules, job rows, filters, confirmations, and the operation tray using existing tokens and frame materials.
- [x] 8.2 Add responsive rules for full-width working surfaces, dialogs, toolbars, and operation rows at 390px without page-local global decoration.
- [x] 8.3 Extend CSS contract tests for theme material reuse, radius limits, and nested-frame safety.
- [x] 8.4 Replace the narrow-screen top navigation stack with a theme-aware off-canvas text sidebar, left-edge effect handle, bounded swipe-open/close behavior, and accessible dismissal.
- [x] 8.5 Add focused component and CSS contract coverage for mobile labels, drawer state semantics, gesture thresholds, and no-flow layout.
## 9. Verification
- [x] 9.1 Run `cd platform_web && npm run typecheck`.
- [x] 9.2 Run `cd platform_web && npm test`.
- [x] 9.3 Run `cd platform_web && npm run build`.
- [x] 9.4 Run browser acceptance for all five first-party areas in black-mecha and magical-girl themes at desktop and 390px, including mobile drawer open/close, confirmation, and failure recovery.
- [x] 9.5 Scan rendered first-party pages for forbidden raw key, token, secret, path, PID, socket, credential, DSN, RCON, and direct Run endpoint fragments.
- [x] 9.6 Run `scripts/check-structure.sh`, `openspec validate enrich-platform-operations-console --strict`, and both repository `git diff --check` commands, then record evidence.
## Verification Evidence
- 2026-07-18 15:25 CST: `npm run typecheck`, `npm run build`, and the full Vitest suite passed (24 files, 132 tests).
- In-app browser acceptance passed against the real local Platform stack for 首页、服务器管理、插件市场、用户管理、AI 提供商管理 and server detail in `mecha-black` and `magical-girl` at 1440x960 and 390x844 (24 route/theme/viewport checks, zero horizontal overflow, zero console errors).
- The 390px sidebar stayed outside page flow (`mainTop=0`, `scrollWidth=390`), opened as a 300px icon-and-Chinese-text drawer, and closed by route selection; both themes were visually inspected.
- Confirmation cancellation preserved plugin state and dispatched no mutation. Real plugin persisted responses populated the session operation tray; a duplicate server ID produced a real Platform failure while preserving the form, and a corrected ID retry succeeded. A real dependency validation failure remained traceable in the staged task dialog.
- Rendered-page scans found no raw key/token/secret value, host path, PID, socket, credential, DSN, RCON value, or direct Run endpoint across all 24 route states. Safe ordinary labels such as key presence and non-projection notices were intentionally retained.
- `scripts/local-debug-smoke.sh` passed using Run-reported capabilities; absent `distribution.build` was verified as unavailable without fake success. `bash -n` and `node --check platform_web/acceptance/browser-acceptance.mjs` passed.
- `scripts/check-structure.sh`, `openspec validate enrich-platform-operations-console --strict`, main repository `git diff --check`, and independent Run repository `git diff --check` all passed.
- Structured browser evidence: `/private/tmp/browser-local-debug-acceptance-9k/browser-acceptance/item-9-evidence.json`.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-20
@@ -0,0 +1,98 @@
## Context
The current platform already has the foundation for plugin runtime declarations, Client Manager build/deploy/control/update/rollback/uninstall, component-key registration, heartbeat, safe status projections, log ingest, artifact records, config diff review, remote access declarations, and backup metadata. The SCUM example manifest also declares a `custom-client` lifecycle and `game-client.bridge` capability, but the bridge is only a placeholder: there is no durable command domain, snapshot ingest/query model, bridge service, repository, DTO, or API surface.
The reference SCUM repositories contain useful behavior: a companion client that can interact with the game window and OCR, server operations and command flows, SCUM log parsing, player/squad/vehicle/flag state, backups, restarts, rewards, events, and database-backed queries. They also contain patterns that must not be copied into this platform: shared credentials, insecure TLS skip, arbitrary terminal commands, arbitrary SQL, raw host paths, direct run sockets, direct cloud credentials, and SCUM business rules embedded into executor code.
The intended ownership model is:
- `game.scum` plugin owns SCUM semantics: pages, schemas, commands, players, squads, vehicles, flags, logs, database query templates, backup/restart/event policy, and `scum_client` companion behavior.
- Platform owns generic product infrastructure: auth, permission checks, durable queue, scheduling, audit, persistence, safe projections, and plugin-page APIs.
- Independent Run owns generic privileged execution only: process supervision, bounded file/SQLite/archive operations, and artifact transfer. No SCUM-specific source tree is added to this repository.
## Goals / Non-Goals
**Goals:**
- Introduce a generic Game Client Bridge that supports authenticated companion clients, durable commands, command claims, acknowledgements, results, cancellation, expiry, idempotency, fencing, and typed snapshot ingestion/query.
- Add SCUM plugin operations that declare commands, snapshots, permissions, approval levels, page contracts, and companion-client expectations.
- Align the SCUM plugin manifest and the real `scum_client` model so generated packages use Platform Client Manager registration/session and bridge APIs instead of legacy `/api/v1/scum-clients/*` shared-token endpoints.
- Preserve channel isolation: game-client bridge traffic does not block run control, jobs, log ingest, or artifact transfer.
- Keep raw credentials, host paths, SQL text, direct sockets, and component secrets out of plugin pages and browser-visible DTOs.
**Non-Goals:**
- Do not implement SCUM business logic inside independent Run.
- Do not add a `run/` source tree back to this repository.
- Do not expose arbitrary shell, arbitrary SQL, generic remote desktop, direct cloud storage credentials, QQ/SMS/music/Douyin/provider workflows, host sales, billing, or unrelated SaaS marketplace features.
- Do not auto-ban or auto-punish players from heuristics in the first bridge phase; moderation begins as evidence, alerts, and operator-approved actions.
- Do not require all legacy SCUM robot features to ship in one implementation pass.
## Decisions
### Decision: Separate Game Client Bridge from Run lifecycle channels
Platform will add a separate bridge domain and API for companion-client commands and snapshots. It will not reuse Run job leases, log batches, artifact chunks, or lifecycle control endpoints for game-window operations.
Rationale: the existing run-contracts already state that the optional game client bridge is separate from run lifecycle, control registration, job handling, log ingest, and artifact transport. Keeping it separate prevents game commands or large snapshots from delaying heartbeat, job acknowledgement, log upload, or artifact transfer.
Alternative considered: model every companion action as a Run job. That would blur operator-visible game operations with machine-side lifecycle execution, make SCUM commands look like generic privileged jobs, and increase the risk of leaking host/executor details into plugin pages.
### Decision: Reuse Client Manager identity for companion clients
`scum_client` will be deployed and supervised through the existing Client Manager lifecycle. Bridge APIs will require a valid component session bound to server instance, plugin, profile key, artifact, key generation, deployment generation, capabilities, and expiry.
Rationale: the platform already has component-key generation, registration signatures, session revocation, heartbeat, health projection, and staged update/rollback. Extending from that identity avoids introducing a second secret model.
Alternative considered: preserve legacy shared `SCUMClientCredential` and `/api/v1/scum-clients/hello|heartbeat|commands|results|snapshots`. That pattern cannot meet current security boundaries because one shared credential can outlive deployment generations, cannot fence stale packages cleanly, and was paired with insecure TLS behavior in the reference client.
### Decision: Let plugins declare SCUM semantics, not Platform or Run
The `game.scum` plugin will declare command catalog entries, snapshot schemas, query templates, page contracts, permission scopes, and approval levels. Platform will validate and persist these declarations, enforce auth/audit/lifecycle mechanics, and expose safe bridge APIs. Run will only execute generic capabilities requested by Platform.
Rationale: the user correctly pointed out that these are SCUM plugin features. Putting SCUM semantics in Platform or Run would make the generic layers harder to reuse for other games and would violate the repository boundary that Run stays independent.
Alternative considered: add first-class SCUM domain services directly to Platform. That would produce faster short-term UI but would freeze SCUM-specific concepts into platform core.
### Decision: Use typed templates for database and file operations
SCUM database reads will be exposed as plugin-declared read-only query templates with typed parameters and bounded result schemas. Backups and restart automation will be declared as SCUM logical policies but executed through generic Platform/Run operations.
Rationale: the reference projects include useful SCUM.db and maintenance behavior, but arbitrary SQL or raw path access is not acceptable in the plugin-page boundary. Template declarations preserve common workflows while keeping operations reviewable and enforceable.
Alternative considered: expose a generic SQL console or file browser to plugin pages. That would violate the existing platform rule that pages never receive DSNs, credentials, host paths, or direct Run endpoints.
### Decision: Start moderation as evidence and approval flows
Duplicate IP, mine, unlock, trade, and suspicious activity signals will initially create typed evidence, alerts, and suggested actions. Destructive or punitive actions require explicit operator approval and audit.
Rationale: the reference robot contains powerful heuristics, but automatic punishments have high false-positive and abuse risk. Approval-first flows are safer and still make the signals useful.
Alternative considered: directly port automatic punish/ban behavior. That is out of scope for the first bridge and would require separate governance requirements.
## Risks / Trade-offs
- Bridge queue and snapshot persistence can become broad quickly -> Mitigation: phase implementation around a small generic state machine, bounded payload sizes, schema versioning, retention, and server-scoped query filters.
- Real `scum_client` currently reads embedded `config.yaml` and does not parse the manifest's `--config config.json` argument -> Mitigation: update the SCUM plugin declaration and companion bootstrap together; support a generated config format that carries Platform registration settings without raw secrets in browser-visible DTOs.
- Snapshot schemas may drift from actual SCUM output -> Mitigation: version schemas, persist raw diagnostic excerpts only in redacted server-side records when needed, and keep plugin validators close to parser code.
- Remote read-only SQLite transport currently has gaps around payload/input propagation -> Mitigation: implement bridge database templates only after the remote access request path preserves declared inputs end to end.
- Frontend scope could sprawl into the whole legacy admin product -> Mitigation: first pages should cover operationally central SCUM surfaces only: client health, commands, players/sessions, vehicles/squads/flags, semantic logs, and maintenance.
- Long-running commands may conflict with deployment updates or session resets -> Mitigation: command claims include component session, deployment generation, lease expiry, and fencing tokens; stale sessions cannot ack or complete current commands.
## Migration Plan
1. Add Platform bridge domain, DTOs, repository interfaces, persistence, service methods, validators, routes, and tests.
2. Extend plugin manifest/schema validation for game-client command catalogs, snapshot schemas, approval levels, and page bridge contracts.
3. Update the SCUM example plugin manifest from local proof placeholders to a real `game.scum` lifecycle/client declaration aligned with generated config and Client Manager registration.
4. Add SCUM plugin page/API types and initial UI surfaces using safe Platform projections.
5. Adapt `scum_client` packaging expectations so it registers and heartbeats through Client Manager sessions and uses bridge command/snapshot APIs.
6. Add typed SCUM log parsing, database query templates, backup/restart declarations, and event/reward flows in later task groups after the bridge is verified.
7. Run `openspec validate implement-game-client-bridge-and-scum-operations --strict`, focused backend/frontend/plugin tests, and `scripts/check-structure.sh`.
Rollback is feature-flag-like by declaration: servers without a deployed compatible Client Manager or without a plugin-declared bridge catalog see disabled bridge actions and no command dispatch. Existing run lifecycle, log ingest, and plugin registry behavior remains intact.
## Open Questions
- Which exact SCUM operations should be enabled in the first UI pass: read-only snapshots plus announcements, or also gifts/rewards/restarts?
- Should bridge command payload/result bodies be stored entirely in Platform DB for the first pass, or split larger artifacts to the artifact channel once payloads exceed a small threshold?
- Does `scum_client` remain in the external SCUM repository with generated packaging metadata, or should a minimal companion fixture be added under the plugin example for local smoke tests only?
@@ -0,0 +1,30 @@
## Why
The SCUM companion client, robot workflows, and run-side helpers contain useful server-operations behavior, but their current shape mixes SCUM product semantics with ad hoc transport, credentials, host paths, and executor responsibilities. We need a first-party bridge that lets `game.scum` own SCUM-specific commands, snapshots, and pages while Platform and Run provide only generic secure infrastructure.
## What Changes
- Add a generic Game Client Bridge capability for durable, authenticated component commands, command lifecycle tracking, cancellation, expiry, idempotency, fencing, result recording, and versioned snapshot ingest/query.
- Add SCUM plugin operations on top of that bridge: command catalog, snapshot schemas, page contracts, permissions, and approval levels for players, squads, vehicles, flags, sessions, logs, database query templates, backups, restarts, and events.
- Adapt the real `scum_client` model into a plugin-owned companion component that registers through the Platform Client Manager path, heartbeats securely, claims bridge commands, returns results, and uploads typed snapshots.
- Keep independent Run free of SCUM business logic. Run may deploy, supervise, execute bounded process/file/SQLite/archive capabilities, and report lifecycle state, but SCUM semantics remain declared by the plugin and mediated by Platform.
- Replace unsafe legacy patterns from the reference projects with platform-mediated equivalents: no arbitrary terminal, no arbitrary SQL, no raw host paths, no shared credentials, no direct run sockets, no insecure TLS skip, and no script-based arbitrary URL self-update.
## Capabilities
### New Capabilities
- `game-client-bridge`: Defines the platform bridge for authenticated companion clients, durable command queues, command result flow, cancellation/expiry semantics, snapshot ingestion, snapshot querying, retention, and audit trails.
- `scum-operations`: Defines the SCUM plugin-owned operational model, including typed commands, typed snapshots, pages, permissions, approval policy, log semantics, database query templates, backup/restart policies, and client integration requirements.
### Modified Capabilities
- None.
## Impact
- Backend Platform: new API routes, DTOs, domain types, repositories, services, persistence models, validation rules, permissions, and audit events for the Game Client Bridge.
- Platform Web: bridge-aware SCUM operation views that preserve the magical-girl crystal-moonlight console direction and do not receive raw credentials or host paths.
- Plugins: `plugins/examples/scum-server-plugin` gains real `game.scum` command catalogs, snapshot schemas, page contracts, permissions, and lifecycle/client declarations aligned with the real companion client.
- Companion Client: `scum_client` behavior is migrated from legacy shared-token endpoints to Platform Client Manager registration/session and bridge command/snapshot APIs.
- Run Executor: no SCUM-specific source is added to this repository; Run remains an independent generic executor for declared process, file, SQLite, artifact, and packaging operations.
@@ -0,0 +1,119 @@
## ADDED Requirements
### Requirement: Component sessions authenticate bridge access
The Platform SHALL require every Game Client Bridge request from a companion client to use a valid component session issued through the Client Manager registration flow.
#### Scenario: Valid component session uses bridge capability
- **WHEN** a deployed companion client registers with the current component key generation, deployment generation, and `game-client.bridge` capability
- **THEN** the Platform accepts bridge requests for the bound server instance, plugin, profile key, artifact, and session expiry window
#### Scenario: Stale component session is rejected
- **WHEN** a companion client uses a session from a revoked key generation, expired session, old deployment generation, or undeclared bridge capability
- **THEN** the Platform rejects the bridge request without returning raw key material or internal secret locations
### Requirement: Commands are durable and fenced
The Platform SHALL persist Game Client Bridge commands with lifecycle state, idempotency key, expiry, priority, declared command type, payload reference or inline bounded payload, target server instance, plugin, requester, approval state, claim lease, fencing token, and audit metadata.
#### Scenario: Operator queues declared bridge command
- **WHEN** an authorized operator queues a command declared by the active plugin bridge catalog
- **THEN** the Platform stores the command as pending, records an audit event, and exposes only safe command status to plugin pages
#### Scenario: Duplicate idempotency key is reused
- **WHEN** the same requester submits the same command type with the same idempotency key for the same server instance
- **THEN** the Platform returns the existing command instead of creating a duplicate command
#### Scenario: Expired command is not claimed
- **WHEN** a pending command has passed its expiry time before a companion client claims it
- **THEN** the Platform marks the command expired and prevents later claim or execution
### Requirement: Companion clients claim and complete commands
The Platform SHALL let authenticated companion clients claim pending bridge commands in bounded batches and complete them only with the active claim lease and fencing token.
#### Scenario: Client claims pending command batch
- **WHEN** an online companion client polls for bridge commands for its bound server instance and profile key
- **THEN** the Platform returns only eligible pending commands, marks them claimed, assigns leases, and includes fencing tokens
#### Scenario: Stale claim cannot complete command
- **WHEN** a companion client submits an ack or result with an expired lease, stale fencing token, or mismatched component session
- **THEN** the Platform rejects the update and leaves the current command state protected from stale completion
#### Scenario: Command result is recorded
- **WHEN** the active claimant completes a command with a success or failure result
- **THEN** the Platform stores sanitized result metadata, updates command status, records completion time, and emits an audit event
### Requirement: Operators can cancel pending or claimed commands
The Platform SHALL allow authorized operators to cancel bridge commands that are not already terminal and SHALL prevent cancelled commands from being executed or completed as successful.
#### Scenario: Pending command is cancelled
- **WHEN** an authorized operator cancels a pending command
- **THEN** the Platform marks the command cancelled and excludes it from future claim batches
#### Scenario: Claimed command is cancelled before completion
- **WHEN** an authorized operator cancels a claimed command
- **THEN** the Platform records the cancellation and rejects later success results from the old claim
### Requirement: Snapshots are versioned and typed
The Platform SHALL ingest Game Client Bridge snapshots only when their type, schema version, sequence, source component, payload shape, and retention policy match active plugin declarations.
#### Scenario: Client uploads declared snapshot
- **WHEN** a companion client uploads a snapshot that matches a declared snapshot type and schema version
- **THEN** the Platform stores it with server instance, plugin, profile key, source session, sequence, observed time, and retention metadata
#### Scenario: Snapshot sequence is stale
- **WHEN** a companion client uploads a snapshot with a sequence older than or equal to the latest accepted sequence for the same stream
- **THEN** the Platform rejects or quarantines the stale snapshot according to validation policy and does not replace the current projection
#### Scenario: Plugin page queries snapshots
- **WHEN** an authorized plugin page requests snapshots for an owned server instance
- **THEN** the Platform returns bounded safe projections without raw component secrets, host paths, direct sockets, or unbounded raw dumps
### Requirement: Bridge traffic is isolated from Run channels
The Platform SHALL keep Game Client Bridge command and snapshot traffic separate from Run control heartbeat, job acknowledgement, log ingest, and artifact transfer channels.
#### Scenario: Large snapshot ingestion does not block control
- **WHEN** a companion client uploads a large but allowed snapshot payload
- **THEN** Run control heartbeat, job acknowledgement, and log upload remain independently serviceable through their own channels
#### Scenario: Bridge unavailable does not disable server lifecycle
- **WHEN** the Game Client Bridge service is unavailable or no companion client is online
- **THEN** existing Run lifecycle actions, log ingest, artifact transfer, and Client Manager lifecycle projections continue to operate
### Requirement: Browser-visible bridge DTOs are safe projections
The Platform SHALL expose only safe bridge declarations, command statuses, results, snapshots, availability reasons, and audit references to plugin pages.
#### Scenario: Plugin page loads bridge state
- **WHEN** a plugin page loads bridge state for a server instance
- **THEN** the response excludes raw credentials, component keys, sessions, DSNs, host paths, direct Run endpoints, sockets, and storage provider credentials
### Requirement: Bridge records are retained and audited
The Platform SHALL apply bounded retention to bridge commands, results, snapshots, and audit references while preserving enough metadata for operator review and troubleshooting.
#### Scenario: Retention job expires old bridge records
- **WHEN** bridge records exceed configured retention limits
- **THEN** the Platform expires or compacts old records without exposing deleted payloads through plugin page APIs
@@ -0,0 +1,127 @@
## ADDED Requirements
### Requirement: SCUM plugin owns SCUM operation semantics
The `game.scum` plugin SHALL declare SCUM-specific commands, snapshot schemas, log event schemas, database query templates, permissions, approval levels, page contracts, and policy labels.
#### Scenario: Platform loads SCUM bridge declarations
- **WHEN** the Platform registers the SCUM plugin manifest
- **THEN** it validates the declared SCUM operation catalog and stores safe declarations without adding SCUM business logic to independent Run
#### Scenario: Unknown SCUM command is rejected
- **WHEN** a plugin page or operator attempts to queue a SCUM command that is not declared by the active SCUM plugin catalog
- **THEN** the Platform rejects the command before it reaches a companion client
### Requirement: SCUM companion client uses Platform identity and bridge APIs
The SCUM companion client SHALL register and heartbeat through the Platform Client Manager component-session flow and SHALL use Game Client Bridge command and snapshot APIs for game-window interaction.
#### Scenario: Generated client package starts with platform config
- **WHEN** a SCUM Client Manager package is generated and deployed
- **THEN** its runtime configuration aligns with the actual companion client bootstrap and includes only the material required to register with Platform through the current component-key generation
#### Scenario: Legacy shared-token endpoint is not used
- **WHEN** a SCUM companion client exchanges commands or snapshots with Platform
- **THEN** it does not use legacy shared-token `/api/v1/scum-clients/hello`, `/heartbeat`, `/commands`, `/results`, or `/snapshots` endpoints
#### Scenario: Insecure TLS skip is not allowed
- **WHEN** the SCUM companion client connects to Platform
- **THEN** it must not disable certificate verification through an unconditional insecure TLS setting
### Requirement: SCUM snapshots cover core operational state
The SCUM plugin SHALL define typed snapshot schemas for at least online sessions, players, squads, vehicles, flags or territories, and companion health diagnostics.
#### Scenario: Player snapshot is ingested
- **WHEN** the SCUM companion client uploads a declared player or online-session snapshot
- **THEN** Platform stores a versioned safe projection that plugin pages can query by server instance and observed time
#### Scenario: Vehicle and flag snapshots are ingested
- **WHEN** the SCUM companion client uploads declared vehicle, squad, flag, or territory snapshots
- **THEN** Platform validates the schema version and sequence before updating the current projection
### Requirement: SCUM command catalog is bounded and permissioned
The SCUM plugin SHALL expose only declared, typed, permission-scoped game commands such as announcements, player lookup, reward delivery, event actions, maintenance preparation, and safe companion diagnostics.
#### Scenario: Operator queues announcement
- **WHEN** an authorized operator queues a declared SCUM announcement command
- **THEN** Platform records the requester, approval state, command payload, idempotency key, and audit event before the companion client can claim it
#### Scenario: Risky command requires approval
- **WHEN** a SCUM command is marked as risky, destructive, economy-affecting, or punitive
- **THEN** Platform requires the declared approval level before making the command claimable
### Requirement: SCUM moderation begins as evidence and review
The SCUM plugin SHALL model suspicious duplicate IP, unlock, mine, trade, kill, admin, and economy signals as evidence, alerts, and operator-reviewed recommendations by default.
#### Scenario: Suspicious event is parsed
- **WHEN** SCUM semantic log parsing detects a suspicious event pattern
- **THEN** Platform records a typed evidence event or alert without automatically banning, punishing, or modifying the player
#### Scenario: Operator approves punitive action
- **WHEN** an operator chooses a punitive SCUM action from a recommendation
- **THEN** Platform applies the command catalog permission and approval rules before dispatching any companion command
### Requirement: SCUM logs are parsed into typed events
The SCUM plugin SHALL define typed semantic log events for chat, login, logout, kill, trade, mine, unlock, admin, and performance records.
#### Scenario: Chat log event is parsed
- **WHEN** SCUM chat log lines are ingested
- **THEN** Platform stores typed chat events that plugin pages can filter by player, time range, and server instance
#### Scenario: Performance log event updates metrics
- **WHEN** SCUM performance log lines are ingested
- **THEN** Platform maps FPS and entity counts into bounded metric projections and alert inputs
### Requirement: SCUM database access uses read-only templates
The SCUM plugin SHALL declare read-only SCUM.db query templates with typed parameters, bounded result schemas, and permission scopes instead of exposing arbitrary SQL.
#### Scenario: Operator runs player lookup template
- **WHEN** an authorized operator runs a declared player lookup query template
- **THEN** Platform dispatches a bounded read-only request and returns only the declared result columns
#### Scenario: Arbitrary SQL is requested
- **WHEN** a plugin page submits SQL text that is not backed by a declared query template
- **THEN** Platform rejects the request and does not dispatch it to Run or the companion client
### Requirement: SCUM backup and restart policy remains plugin-declared
The SCUM plugin SHALL declare backup scopes, retention policy, restart schedules, warning announcements, and update-check policy as SCUM operational policy while Platform and Run execute only generic jobs.
#### Scenario: Scheduled restart is prepared
- **WHEN** a SCUM restart schedule reaches its warning window
- **THEN** Platform queues declared SCUM announcement commands and generic lifecycle actions according to plugin policy and operator approvals
#### Scenario: Backup is requested
- **WHEN** an authorized operator requests a SCUM backup
- **THEN** Platform records the logical SCUM backup scope and dispatches generic archive/artifact operations without exposing raw host paths or storage credentials to the plugin page
### Requirement: SCUM operation pages use safe Platform projections
The SCUM plugin pages SHALL render bridge state, snapshots, commands, logs, backup/restart policy, and review flows using Platform-mediated DTOs only.
#### Scenario: SCUM operations page loads
- **WHEN** a user opens the SCUM operations page for a server instance
- **THEN** the page can display safe bridge status, companion health, current snapshots, command availability, and recent results without receiving raw secrets, host paths, DSNs, direct Run sockets, or component session material
@@ -0,0 +1,53 @@
## 1. Platform Bridge Foundation
- [x] 1.1 Add Game Client Bridge domain types for commands, command states, claims, results, cancellations, snapshots, snapshot streams, retention metadata, and audit references.
- [x] 1.2 Add bridge DTOs and validation rules for queue, claim, ack/result, cancel, snapshot ingest, snapshot query, and safe browser projections.
- [x] 1.3 Add repository interfaces and in-memory or durable store implementations for bridge commands, snapshots, stream sequence tracking, and retention queries.
- [x] 1.4 Add service methods for command creation, idempotency reuse, claim leasing, fencing-token checks, terminal result handling, cancellation, expiry, and audit recording.
- [x] 1.5 Add component-session authorization checks so only current Client Manager sessions with `game-client.bridge` can claim commands or upload snapshots.
## 2. Platform API Surface
- [x] 2.1 Add operator-facing API routes for listing bridge declarations/status, queueing declared commands, cancelling commands, reading command results, and querying snapshots.
- [x] 2.2 Add companion-facing API routes for claiming command batches, acknowledging commands, posting results, uploading snapshots, and reporting bridge diagnostics.
- [x] 2.3 Ensure bridge routes expose only safe projections and never expose component keys, sessions, secret refs, host paths, DSNs, direct Run endpoints, sockets, or storage credentials.
- [x] 2.4 Add bridge retention and expiry reconciliation paths for old commands, old results, stale claims, and expired snapshots.
## 3. Plugin Manifest and SDK Contracts
- [x] 3.1 Extend plugin manifest schema and validation for game-client command catalogs, snapshot schemas, approval levels, permissions, retention policy, and page bridge contracts.
- [x] 3.2 Extend plugin SDK/API types so plugin pages can call Platform-mediated bridge actions without receiving raw executor or component secrets.
- [x] 3.3 Fix remote-access request input propagation needed by declared read-only database templates before enabling SCUM.db query operations.
- [x] 3.4 Add manifest/schema tests for rejected arbitrary SQL, arbitrary shell, raw paths, undeclared commands, unsafe capabilities, and missing approval metadata.
## 4. SCUM Plugin Operations
- [x] 4.1 Update the SCUM plugin manifest from local proof placeholders to real `game.scum` operation declarations for lifecycle, client manager, bridge commands, snapshots, logs, and pages.
- [x] 4.2 Align SCUM Client Manager packaging/config declarations with the real companion client bootstrap instead of nonexistent `configs/client.template.json`, `config.json`, and unsupported `--config` assumptions.
- [x] 4.3 Add typed SCUM snapshot schemas for online sessions, players, squads, vehicles, flags or territories, and companion health diagnostics.
- [x] 4.4 Add bounded SCUM command catalog entries for announcements, safe diagnostics, player lookup, reward/event flows, restart preparation, and maintenance actions with permissions and approval levels.
- [x] 4.5 Add read-only SCUM.db query template declarations with typed parameters and bounded result schemas.
- [x] 4.6 Add SCUM semantic log event declarations for chat, login, logout, kill, trade, mine, unlock, admin, and performance events.
## 5. Frontend Operations Surface
- [x] 5.1 Add Platform Web API client/types for bridge declarations, command status, command results, snapshot projections, approval state, and bridge diagnostics.
- [x] 5.2 Add SCUM operations page contracts and route wiring through the existing plugin page bridge model.
- [x] 5.3 Build the first SCUM operations UI for companion health, command queue/results, players/sessions, vehicles/squads/flags, semantic logs, and maintenance policy using safe Platform projections.
- [x] 5.4 Preserve the `platform_web` magical-girl crystal-moonlight operations-console style and avoid page-local fixed decorative effects outside `MagicalParticleLayer`.
## 6. Companion Client Integration
- [x] 6.1 Define the generated companion config shape used by Platform Client Manager registration and bridge APIs without exposing browser-visible raw secrets.
- [x] 6.2 Adapt the SCUM companion client integration path away from legacy shared-token `/api/v1/scum-clients/*` endpoints toward Platform component-session registration, heartbeat, command claim/result, and snapshot upload.
- [x] 6.3 Remove unconditional insecure TLS behavior from the companion integration path and add tests or checks for secure transport defaults.
- [x] 6.4 Add local smoke fixtures or documentation showing how a compatible `scum_client` package claims a command and uploads a typed snapshot.
## 7. Tests and Verification
- [x] 7.1 Add backend unit tests for bridge idempotency, claim leasing, fencing, cancellation, expiry, result recording, component-session authorization, safe projections, and snapshot sequence handling.
- [x] 7.2 Add plugin manifest validation tests for the SCUM operation declarations and unsafe legacy-pattern rejection.
- [x] 7.3 Add frontend tests for SCUM bridge API typing, disabled availability reasons, command approval states, and safe rendering without secrets.
- [x] 7.4 Run focused Go and frontend tests covering changed packages.
- [x] 7.5 Run `openspec validate implement-game-client-bridge-and-scum-operations --strict`.
- [x] 7.6 Run `scripts/check-structure.sh`.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-18
@@ -0,0 +1,80 @@
## Context
Item 9 made the console truthful about API-backed operational state, current-session operations, and safe projections. The remaining production gap is not another dashboard facade; it is durable governance: admission control under capacity pressure, alert lifecycle closure, complete plugin lifecycle state, and real provider-backed AI assistance. The implementation must reuse Platform as the authority and Run as a channelized executor while keeping plugin pages and browser code away from raw secrets, direct sockets, host paths, and provider transport details.
## Goals / Non-Goals
**Goals:**
- Govern server and Run capacity through Platform admission checks, safe endpoint capacity reports, queued/retrying jobs, and explicit capacity-denied responses.
- Persist alerts with source, severity, state, acknowledgement, scoped retry, resolution, suppression windows, audit links, and safe diagnostic text.
- Model complete plugin lifecycle state and compatibility gates in Platform, and drive lifecycle jobs through the existing job channel.
- Add real AI Provider invocation through a provider client that uses Platform-stored key/base URL material and never returns raw credentials or transport details.
- Require AI-generated config changes to produce a diff/recommendation that must be approved before any run-side write job is dispatched.
- Surface governance, alerts, lifecycle, and AI states in existing first-party pages without replacing the visual system or full-width management surfaces.
- Extend Run capacity/lifecycle contracts with bounded metadata only, preserving channel isolation and priority.
**Non-Goals:**
- No billing, cloud host sales, cloud/agent provider marketplace, or SaaS marketplace expansion.
- No arbitrary shell, direct Run socket/endpoint, host path projection, raw PID/socket/DSN/RCON, or raw credential/token/key/base URL exposure.
- No browser/plugin storage of provider secrets.
- No replacement of the five required first-party areas or the black-mecha/magical-girl theme system.
## Decisions
### Decision 1: Platform owns production admission decisions
Run heartbeats report bounded capacity metadata. Platform combines that with server bindings, queued/running job pressure, endpoint capability availability, and configured limits before accepting lifecycle, dependency, backup, update, and plugin jobs. Rejected work returns a safe capacity or compatibility reason and records audit/alert evidence.
Alternative considered: let Run reject after claim. Rejected because operators need immediate Platform feedback, and Run-only rejection creates noisy retry loops.
### Decision 2: Alerts are durable state, not transient UI messages
Capacity pressure, failed lifecycle work, stale endpoints, AI provider failures, plugin compatibility failures, and unsafe request denials create or update durable alert records. Alerts have explicit acknowledgement and resolution transitions with actor and audit metadata. Current-session UI operations remain separate and cannot close durable alerts by themselves.
Alternative considered: derive alerts only from latest jobs/metrics. Rejected because acknowledgement, suppression, and resolution are production workflows that must survive restart.
### Decision 3: Plugin lifecycle state is managed by Platform
Marketplace enablement remains a catalog state, while lifecycle operations track installed plugin version, target server compatibility, dependency status, desired state, current state, upgrade/rollback availability, linked job IDs, and audit/alert summaries. Plugin manifests and bridge calls declare capabilities and purposes, but Platform authorizes and dispatches all jobs.
Alternative considered: plugin pages manage lifecycle locally through bridge state. Rejected because that would bypass durable authorization and job/audit truth.
### Decision 4: Real AI Provider calls use a redacted provider client
Platform selects an active provider, decrypts key/base URL material inside the service boundary, sends bounded requests through a provider client, and returns only safe recommendation/diff/usage metadata. Tests and local mode can still use deterministic clients, but production code must support a real HTTP provider path with redacted failures.
Alternative considered: expose base URLs or keys to plugin pages for direct calls. Rejected by the repository AI Provider rules and secret boundary.
### Decision 5: AI config changes are two-step
AI can suggest a structured diff for configuration or lifecycle inputs. Platform stores the diff preview and requires explicit approval before dispatching a run-side config write job. Approval is scoped to actor/server/plugin/config revision and stale approvals are denied.
Alternative considered: dispatch config writes directly after AI completion. Rejected because AI suggestions must be reviewable before mutation.
### Decision 6: Run receives bounded lifecycle and capacity metadata only
Run protocol additions are limited to safe capacity dimensions, pressure reasons, lifecycle capability names, and logical job inputs. They do not carry raw host paths, process IDs, sockets, credentials, provider configuration, or browser/plugin transport material.
Alternative considered: add a general operations channel. Rejected because existing control/job/log/artifact/game-client channels already define the isolation model.
## Risks / Trade-offs
- [Risk] Alert deduplication can hide repeated incidents. Mitigation: keep occurrence counts, last-seen timestamps, state transitions, and audit references.
- [Risk] Capacity admission can reject recoverable work too early. Mitigation: use explicit retry-after hints, scoped retry, and distinguish hard compatibility failures from temporary pressure.
- [Risk] Real provider calls can leak transport errors. Mitigation: redact provider failures and validate every response before returning it.
- [Risk] Lifecycle state overlaps existing marketplace state. Mitigation: keep marketplace catalog state separate from server/plugin lifecycle installations.
- [Risk] Broad verification may be expensive. Mitigation: add focused unit tests first, then run full platform_web, plugins, platform, run, structure, OpenSpec, diff, and browser checks before completion.
## Migration Plan
1. Add OpenSpec artifacts and validate strictly before implementation.
2. Add shared Platform domain/DTO/validator/model/repo/service support for capacity governance, alerts, plugin lifecycle, and AI diff approvals.
3. Add Platform API routes and route docs with named DTOs and OpenAPI-style handler comments.
4. Extend plugin manifest/SDK/bridge contracts and examples with lifecycle and mediated AI purpose metadata.
5. Extend Run protocol/runtime capacity and lifecycle metadata without crossing channel boundaries.
6. Update platform_web contracts/pages/theme/tests to surface capacity, alerts, lifecycle, and AI diff approval using existing first-party surfaces.
7. Run full verification and record evidence in this change's tasks.
Rollback is additive: remove the new governance/lifecycle/alert/AI diff approval routes and UI panels, while preserving existing item 9 console behavior and earlier durable job/channel mechanics.
@@ -0,0 +1,30 @@
## Why
The platform now has a real API-backed operations console and durable Run channels, but production operators still need stronger capacity governance, alert closure, full plugin lifecycle state, and a non-mock Platform-mediated AI Provider path. These areas were intentionally left as future work in prior changes and now need to become first-class, durable workflows without weakening the existing browser, plugin, Run, and secret boundaries.
## What Changes
- Add production capacity governance for Run endpoints and server instances: safe capacity reports, admission decisions, pressure alerts, and bounded retry/reconciliation.
- Add durable alert rules/events with acknowledgement, scoped retry, resolution, audit evidence, and UI surfacing across overview, server detail, maintenance, and operation history.
- Complete plugin lifecycle beyond marketplace state: install, enable, disable, upgrade, rollback, retire, dependency checks, compatibility gates, lifecycle jobs, and durable audit/alert hooks.
- Replace mock-only AI invocation with a real provider-client integration path that keeps keys and base URLs in Platform, validates plugin purposes, returns redacted recommendations, and requires reviewable diff approval before config writes.
- Extend Run channel contracts only with bounded capacity and lifecycle metadata; do not add direct browser-to-Run access or plugin-owned transports.
- Preserve the required first-party areas and the black-mecha / magical-girl crystal-moonlight operations console style.
## Capabilities
### New Capabilities
- `production-operations-governance`: Platform-owned capacity governance, alert closure, complete plugin lifecycle, and real mediated AI Provider operations.
### Modified Capabilities
None.
## Impact
- Affects `platform/` domain, DTOs, validators, repositories, services, API routes, tests, and docs.
- Affects `platform_web/` API contracts, page contracts, first-party pages, shared operation components, theme styles, browser acceptance, and tests.
- Affects `plugins/` manifest schema, SDK/bridge contracts, examples, validation tests, and docs.
- Affects the independent `run/` protocol/runtime with bounded capacity/lifecycle metadata and tests.
- Does not add billing, cloud host sales, cloud/agent provider marketplace, arbitrary shell, direct Run socket/endpoint exposure, or raw credential projection.
@@ -0,0 +1,109 @@
## ADDED Requirements
### Requirement: Platform governs production capacity
Platform SHALL make admission and scheduling decisions using persisted server bindings, endpoint capability support, current Run capacity reports, durable job pressure, and configured safety limits before dispatching production lifecycle work.
#### Scenario: Capacity accepts bounded work
- **WHEN** an authorized operator requests a plugin lifecycle, dependency, backup, update, or server lifecycle operation and an assigned endpoint is online with matching capabilities and available capacity
- **THEN** Platform MUST create one durable job with safe capacity metadata, audit the admission decision, and expose a safe job projection
#### Scenario: Capacity denies pressure safely
- **WHEN** the assigned endpoint is offline, stale, missing capability support, over its configured running/queued limits, or under log/artifact/backlog pressure
- **THEN** Platform MUST reject or defer the request with a safe retry-after/capacity reason, MUST NOT fabricate success, and MUST NOT expose raw endpoint addresses, sockets, paths, credentials, leases, or session tokens
### Requirement: Run reports bounded capacity without blocking priority channels
Run SHALL report only bounded capacity dimensions on control heartbeat and job claim metadata, and SHALL keep control, job lifecycle, log ingest, artifact transfer, and optional game-client bridge channels independent.
#### Scenario: Artifact backlog exists during heartbeat
- **WHEN** artifact or component transfer backlog is present
- **THEN** Run MUST continue sending control heartbeat and job ack/result/cancel/reconcile metadata without embedding artifact chunks, host paths, local file names, credentials, sockets, or provider configuration
#### Scenario: Capacity report is sanitized
- **WHEN** Platform or browser views Run endpoint capacity
- **THEN** visible capacity MUST include only logical counts, percentages, pressure codes, and timestamps, never raw host paths, PIDs, sockets, DSNs, RCON values, secrets, leases, or direct endpoint URLs
### Requirement: Alerts are durable and closeable
Platform SHALL persist alert records for production incidents including capacity pressure, endpoint staleness, failed jobs, lifecycle failures, plugin compatibility failures, unsafe request denials, and AI provider failures.
#### Scenario: Alert is acknowledged and resolved
- **WHEN** an authorized operator acknowledges and later resolves an active alert
- **THEN** Platform MUST update durable alert state, actor, timestamps, audit references, and safe resolution notes without mutating unrelated alerts
#### Scenario: Alert retry remains scoped
- **WHEN** an operator retries a failed alert source such as endpoint capacity refresh, plugin lifecycle check, or AI provider test
- **THEN** only that source is retried, busy state prevents duplicate submission, and success/failure is reflected from Platform responses rather than local timers
### Requirement: Plugin lifecycle is complete and platform-mediated
Platform SHALL manage plugin lifecycle installations separately from marketplace catalog state, including install, enable, disable, upgrade, rollback, retire, dependency checks, compatibility gates, desired/current state, job linkage, audit history, and alert integration.
#### Scenario: Plugin upgrade is approved
- **WHEN** an authorized operator approves an upgrade for a server-bound plugin installation with a compatible target version, satisfied dependency checks, and endpoint capability support
- **THEN** Platform MUST create a durable lifecycle job and transition state only from job results or reconciliation evidence
#### Scenario: Plugin rollback is repeated
- **WHEN** rollback is retried with the same idempotency key and immutable inputs
- **THEN** Platform MUST return the original lifecycle/job result and MUST reject the same key with different immutable inputs
#### Scenario: Unsafe lifecycle input is rejected
- **WHEN** plugin lifecycle metadata, manifest actions, bridge requests, or job inputs contain arbitrary shell, raw credentials, direct Run endpoints, host paths, PIDs, sockets, DSNs, RCON data, unknown capabilities, or undeclared AI purposes
- **THEN** validation MUST reject the request before registration or dispatch
### Requirement: Plugins request AI only through Platform-mediated capability
Plugin manifests, SDK calls, and platform-hosted plugin pages SHALL request AI assistance only through typed Platform bridge/API contracts that declare purpose, request ID, scoped input, and context references.
#### Scenario: Declared AI purpose is invoked
- **WHEN** a plugin invokes a declared AI purpose through the Platform bridge
- **THEN** Platform MUST validate plugin installation state, route permission, server scope, purpose, payload bounds, provider availability, and unsafe text before invoking a provider client
#### Scenario: Undeclared AI purpose is denied
- **WHEN** a plugin invokes an undeclared or currently unauthorized AI purpose
- **THEN** Platform MUST deny the request with a safe error and MUST NOT call a provider client
### Requirement: Real AI Provider integration stays inside Platform
Platform SHALL support a real provider client path that reads provider keys and base URL material only inside Platform service boundaries, invokes enabled providers with bounded requests, and returns redacted responses.
#### Scenario: Real provider returns recommendation
- **WHEN** an enabled provider is selected and the provider client succeeds
- **THEN** Platform MUST return safe recommendation, model, usage, request ID, and optional diff preview metadata without raw API keys, bearer tokens, base URL secrets, transport headers, storage material, host paths, sockets, or credentials
#### Scenario: Provider fails
- **WHEN** provider transport, authentication, rate limit, or model invocation fails
- **THEN** Platform MUST persist a safe audit/alert, return a redacted failure, and MUST NOT expose raw provider URL, headers, keys, request body secrets, or stack traces
### Requirement: AI config changes require reviewable diff approval
AI-generated configuration changes SHALL be persisted as reviewable recommendations or diff previews and SHALL require separate operator approval before Platform dispatches any run-side config write job.
#### Scenario: Diff is approved
- **WHEN** an authorized operator approves a current, matching AI config diff preview for the same server, plugin, actor scope, and config revision
- **THEN** Platform MUST dispatch one bounded config write job and link the job, approval, audit event, and source AI request
#### Scenario: Diff is stale or cancelled
- **WHEN** the config revision changes, the approval is cancelled, or the preview has expired
- **THEN** Platform MUST reject dispatch, preserve the recommendation for review history, and avoid run-side mutation
### Requirement: Console surfaces governance without changing visual direction
platform_web SHALL surface capacity governance, alert closure, plugin lifecycle, and AI diff approval in the existing first-party operations console using real Platform APIs, permissions, confirmation, busy state, scoped retry, and failure recovery.
#### Scenario: Operator closes alert in the console
- **WHEN** an authorized operator acknowledges or resolves an alert
- **THEN** the UI MUST dispatch one Platform request, block duplicate submission while pending, refresh from persisted response, and show failure recovery without claiming local success
#### Scenario: Narrow viewport renders governance surfaces
- **WHEN** the console is rendered at 390px in black-mecha or magical-girl theme
- **THEN** capacity, alerts, lifecycle, AI diff review, confirmations, and operation rows MUST remain readable, bounded, and theme-consistent without page-local global decoration
### Requirement: Verification covers production governance boundaries
The change SHALL include platform tests, run tests, plugin typecheck/tests/manifest validation, platform_web typecheck/tests/build, browser acceptance evidence, structure validation, strict OpenSpec validation, two-repository diff whitespace checks, and forbidden-field scans before tasks are marked complete.
#### Scenario: Verification evidence is recorded
- **WHEN** implementation tasks are completed
- **THEN** `tasks.md` MUST record real command/browser evidence and MUST NOT mark verification complete until those checks pass
@@ -0,0 +1,57 @@
## 1. OpenSpec and Architecture
- [x] 1.1 Create proposal, design, spec, and task artifacts for production operations governance.
- [x] 1.2 Run `openspec validate implement-production-operations-governance --strict` before implementation.
## 2. Platform Capacity, Alerts, and Lifecycle
- [x] 2.1 Add domain/DTO/validator/model/repo/service support for production capacity governance and safe admission decisions.
- [x] 2.2 Add durable alert records with acknowledge, resolve, scoped retry, audit linkage, deduplication, and safe diagnostic text.
- [x] 2.3 Add complete plugin lifecycle installation state, compatibility gates, idempotency fences, upgrade/rollback/retire operations, and job/audit/alert integration.
- [x] 2.4 Add real AI Provider client integration plus redacted provider failure handling and alert/audit evidence.
- [x] 2.5 Add AI config diff preview/approval persistence and dispatch gating before run-side config write jobs.
- [x] 2.6 Update Platform API routes, route docs, protocol docs, and tests.
## 3. Plugin SDK and Bridge
- [x] 3.1 Extend manifest schema and examples with production lifecycle and AI purpose declarations.
- [x] 3.2 Extend SDK/bridge contracts to request lifecycle/AI through Platform-mediated capabilities only.
- [x] 3.3 Add validation/typecheck/tests proving unsafe lifecycle input and raw credential/direct Run fields are rejected.
## 4. Run Protocol and Runtime
- [x] 4.1 Extend Run protocol capacity reports and job metadata with bounded pressure/lifecycle fields only.
- [x] 4.2 Update Run runtime capacity reporting and lifecycle handling without blocking control/job/log/artifact channels.
- [x] 4.3 Add Run tests for capacity sanitization, channel isolation under backlog, and lifecycle metadata validation.
## 5. platform_web Console
- [x] 5.1 Add typed API/contracts for capacity governance, alerts, plugin lifecycle, AI diff preview, and approval.
- [x] 5.2 Surface alerts and capacity on overview, server detail, maintenance, and operation history with confirmation, busy state, scoped retry, persisted responses, and failure recovery.
- [x] 5.3 Surface full plugin lifecycle and AI diff approval in existing first-party pages using shared themed surfaces.
- [x] 5.4 Add tests for permissions, duplicate prevention, failed recovery, forbidden-field omission, and 390px theme-safe rendering.
## 6. Verification
- [x] 6.1 Run platform Go tests.
- [x] 6.2 Run independent Run Go tests.
- [x] 6.3 Run plugins typecheck, tests, and manifest validation.
- [x] 6.4 Run platform_web typecheck, tests, and production build.
- [x] 6.5 Run browser acceptance for the five first-party areas, server detail, alerts, plugin lifecycle, AI diff approval, desktop and 390px, black-mecha and magical-girl.
- [x] 6.6 Scan rendered outputs for raw key/token/secret/base URL secret/path/PID/socket/credential/DSN/RCON/direct Run endpoint fragments.
- [x] 6.7 Run `scripts/check-structure.sh`, `openspec validate implement-production-operations-governance --strict`, and both repository `git diff --check`.
- [x] 6.8 Record real verification evidence in this file before marking verification tasks complete.
## Verification Evidence
- 2026-07-18 19:02 CST: `cd platform && go test ./...` passed for all Platform packages; `cd /Users/tasia/Desktop/code/run && go test ./...` passed for the independent Run repository.
- `cd plugins && npm run typecheck`, `npm test -- --run`, and `npm run validate:manifest` passed: 1 test file / 19 tests and all three example manifests validated. The manifest command was rerun outside the filesystem sandbox because `tsx` requires a local IPC pipe.
- `cd platform_web && npm run typecheck`, `npm test -- --run`, and `npm run build` passed: 26 test files / 135 tests, 1,829 production modules transformed, and the production bundle completed successfully.
- `scripts/local-debug-smoke.sh` and `npm --prefix platform_web run acceptance:browser` passed against the real local Platform and independent Run stack rooted at `/private/tmp/browser-local-debug-acceptance-10o`. `node --check platform_web/acceptance/browser-acceptance.mjs` and `bash -n scripts/local-debug-env.sh scripts/local-debug-smoke.sh scripts/local-debug-start.sh` also passed.
- Capacity evidence recorded a persisted `denied` admission with bounded `queue.limit` and `capability.missing` pressure codes plus a linked durable alert and audit event. Alert cancellation preserved `active`; confirmed acknowledgement persisted `acknowledged`, actor, timestamp, and audit linkage.
- Plugin lifecycle install and enable each produced durable Platform jobs. The persisted installation reached the requested enabled state with linked job and audit IDs; browser scans passed after the lifecycle interactions.
- AI diff cancellation preserved `pending`; explicit approval persisted `approved` and dispatched exactly one `config.write` job. Independent Run completed that job as `succeeded` with a safe `file.write` result at version 2 and an `atomic compare-and-swap file write` audit summary; Platform configuration advanced from version 1 to 2 before the subsequent real `process.stop` request.
- Browser acceptance covered 首页、服务器管理、插件市场、用户管理、AI 提供商管理, server detail, maintenance/operation history, alert closure, plugin lifecycle, and AI diff approval in four scenarios: 1440x960 and 390x844 for `mecha-black` and `magical-girl`. All 38 route/interaction checks reported zero horizontal overflow, zero overlapping controls, and no tiny visible text boxes.
- API and rendered-output scans passed for raw key/token/secret/base URL secret, host path, PID, socket, credential, DSN, RCON, session/direct Run endpoint, and plugin-owned transport fragments. Confirm/cancel, busy duplicate prevention, persisted terminal state, real failure recovery, and scoped retry evidence are included in the structured artifact.
- `scripts/check-structure.sh`, `openspec validate implement-production-operations-governance --strict`, the main repository `git diff --check`, and the independent Run repository `git diff --check` passed. These gates were rerun after recording this evidence.
- Structured browser evidence: `/private/tmp/browser-local-debug-acceptance-10o/browser-acceptance/browser-acceptance-evidence.json` and `/private/tmp/browser-local-debug-acceptance-10o/browser-acceptance/item-10-evidence.json`. Durable Platform/Run result snapshot: `/private/tmp/browser-local-debug-acceptance-10o/platform/metadata.json`.
@@ -30,29 +30,35 @@
## 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.
- [x] 5.1 Add Run protocol payloads and validation for client-manager deploy/control/update/rollback/uninstall, immutable fences, lifecycle progress/results, and endpoint capabilities.
- [x] 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.
- [x] 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.
- [x] 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.
- [x] 5.5 Implement staged update health confirmation, automatic rollback, explicit rollback, stale/revoked generation rejection, re-entry after restart, and real phase reporting.
- [x] 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.
- [x] 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.
- [x] 6.1 Add API types, schemas, client methods, safe action projections, polling/job progress integration, and tests for Client Manager lifecycle summaries and commands.
- [x] 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.
- [x] 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.
- [x] 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.
- [x] 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.
- [x] 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.
- [x] 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.
- [x] 7.4 Run shell/compose checks, `scripts/check-structure.sh`, and `git diff --check` in both the main repository and independent Run checkout.
- [x] 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.
- `plugins`: `npm run typecheck` passed; `npm test` passed (1 file, 18 tests); `npm run validate:manifest` passed for dev, SCUM, and Minecraft manifests (tsx IPC required the approved escalated run).
- `platform`: `go test -count=1 ./...` passed for api/config/domain/dto/model/repo/service/validator packages.
- independent `run`: `go test -count=1 ./...` passed for api/config/protocol/runtime/spool; Client Manager tests cover chunk resume/checksum, restart journal resume, traversal archive rejection, idempotency, stale fences, automatic update restore, safe uninstall, redaction-safe results, and controlled supervisor paths.
- `platform_web`: `npm run typecheck`, `npm test` (20 files, 111 tests), and `npm run build` passed. Added lifecycle API/schema tests, 401/403 behavior remains covered by existing client tests, and source assertions cover secret/path/PID/socket redaction and confirmation flows.
- Browser walkthrough: local Platform-backed console at `http://127.0.0.1:5174/` logged in as the seeded operator, opened `SCUM Alpha` Server Detail, verified the `Client Manager 生命周期` panel and real empty-state gating, switched magical-girl and black-mecha palettes, and checked the panel at 390x844 (`362px` wide, no horizontal overflow).
- Shell/compose: `for file in scripts/*.sh; do bash -n "$file"; done` passed; `docker compose config` passed; `scripts/check-structure.sh` passed; `git diff --check` passed in the main repository and independent run checkout.
- `openspec validate implement-secure-client-manager-lifecycle --strict` passed.