docs(openspec): define SCUM plugin ownership migration
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-28
|
||||
@@ -0,0 +1,75 @@
|
||||
## Context
|
||||
|
||||
The current SCUM work has a generic platform command/log bridge, but the five SCUM feature areas are implemented as SCUM-named services, models, API handlers, and React panels in `platform/` and `platform_web/`. The SCUM plugin only declares schemas and command names. Its Companion can register, heartbeat, claim, acknowledge, complete, and upload snapshots, but has no long-running dispatcher, SCUM command handlers, semantic-log uploader, or event collector.
|
||||
|
||||
The repository requires platform/run communication to remain channelized and forbids plugins from receiving credentials, raw host paths, direct sockets, or raw AI keys. The referenced legacy SCUM client uses OCR and keyboard/mouse automation, which is explicitly excluded from the trajectory feature and is not an acceptable replacement adapter.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Make `plugins/examples/scum-server-plugin/` the owner of SCUM configuration semantics, feature APIs/types/UI, Companion behavior, event parsing, coordinate transforms, and command adapters.
|
||||
- Keep `platform/` limited to reusable plugin primitives: authorization, server isolation, plugin-scoped opaque record storage, review/audit, typed command transport, durable log transport, retention scheduling, and plugin-bundle hosting.
|
||||
- Establish a safe long-running Companion protocol that handles only declared typed commands, emits declared semantic events, and never exposes raw game/database/network data to the browser.
|
||||
- Migrate without discarding existing records until equivalent plugin-owned reads and writes have been verified.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Reintroducing `scum_robot`, `scum_client`, direct game-database access, OCR, screenshots, keyboard/mouse injection, desktop automation, or unrestricted RCON/SQL/JSON commands.
|
||||
- Adding payment, QQ/SMS, cloud, or other legacy robot services.
|
||||
- Automatically banning, punishing, or retrying unknown item-delivery outcomes.
|
||||
- Claiming support for a SCUM version/operation before a versioned adapter has integration evidence.
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Plugin-owned feature modules, generic platform primitives
|
||||
|
||||
SCUM feature contracts, validators, repository adapters, Companion handlers, and UI modules SHALL live under the SCUM plugin directory. The platform SHALL provide generic names and opaque/plugin-scoped payloads rather than SCUM-named domain services or routes.
|
||||
|
||||
The alternative of retaining SCUM services in the platform makes a manifest-only plugin easy to render but permanently couples every SCUM release to the platform binary. It is rejected because it is the ownership failure being corrected.
|
||||
|
||||
### 2. Plugin page bundles mounted by a generic host
|
||||
|
||||
The SCUM plugin SHALL declare a versioned page-bundle entry and page contracts. `platform_web` SHALL authenticate, load the declared bundle through a generic plugin-page host, and provide shared theme/navigation/permission context. It SHALL not import SCUM component classes or branch on `game.scum`.
|
||||
|
||||
The alternative of metadata-only generic forms is insufficient for the map, player timeline, gift preview, and controlled attribute workflow. The alternative of a standalone plugin web application is rejected because it would bypass platform session, tenancy, and theme integration.
|
||||
|
||||
### 3. Long-running SCUM Companion adapter
|
||||
|
||||
The Companion SHALL run a bounded dispatch loop after registration. It SHALL claim declared commands, validate the exact command schema and SCUM capability/version, execute only a registered handler, acknowledge/completely report idempotent typed results, and produce no output containing raw paths, credentials, IPs, database rows, or RCON command text.
|
||||
|
||||
The adapter SHALL include independent handlers for configuration read/patch, semantic log/event production, `reward.deliver`, `player.notify`, and `game-state.patch`. A handler unavailable for a discovered server version SHALL return an explicit unsupported result; the platform must keep the operation disabled.
|
||||
|
||||
Direct raw-RCON or raw-SQL dispatch is rejected: legacy code is reference material only and must be translated into narrow typed adapters.
|
||||
|
||||
### 4. Declared semantic event pipeline
|
||||
|
||||
The Companion SHALL parse only plugin-declared allowed log/extension sources and upload contiguous typed semantic event batches using the durable log channel. Login/logout, player/vehicle position, and vehicle transitions SHALL be emitted only when their source and required fields can be validated. Map coordinate conversion, sampling, and retention declarations remain SCUM-plugin configuration.
|
||||
|
||||
The platform may persist and query events as opaque plugin records for isolation and retention, but it SHALL not contain SCUM-specific parsers or projectors. Events without a verified producer SHALL remain unavailable in the plugin UI rather than being simulated from test data.
|
||||
|
||||
### 5. Staged migration and compatibility
|
||||
|
||||
Migration SHALL proceed feature by feature behind a plugin capability/version flag. Platform-owned SCUM records are read-only migration input until the plugin module has parity tests and at least a controlled end-to-end Companion test. The generic platform host is switched only after the plugin bundle is available; SCUM-specific platform routes/components are removed only after no remaining callers exist.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [SCUM may not expose a safe API for a requested operation] → require capability/version discovery and show disabled/unsupported, never fall back to raw DB writes or automation.
|
||||
- [Plugin bundle isolation introduces a loading/deployment surface] → version page bundles with the manifest, verify integrity, and fail closed to an unavailable-page state.
|
||||
- [Record migration can lose audit traceability] → preserve immutable audit linkage and migration provenance; do not bulk-delete old records before retention expiry and parity verification.
|
||||
- [Semantic log formats can drift with SCUM updates] → version parser adapters, keep fixtures from supported formats, and reject unknown formats without inventing fields.
|
||||
- [Moving too much out of platform duplicates security logic] → keep authorization, tenancy, queue, audit, and storage primitives generic and platform-owned.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Add generic plugin-page bundle and plugin-scoped record/event/command primitives without new SCUM-specific platform APIs.
|
||||
2. Create the SCUM feature module and Companion dispatcher with read-only diagnostics and event-producer proof.
|
||||
3. Migrate configuration and player/event reads, then gifts and state patches behind capability/version gates.
|
||||
4. Replace the hard-coded SCUM imports in the platform host with the generic mount; run compatibility and end-to-end tests against an isolated non-production server.
|
||||
5. Remove SCUM-named platform services/routes/models only after plugin parity, migration audit, and a rollback window. Rollback keeps the prior platform records read-only and disables the plugin capability flag; it never re-enables unsafe execution paths.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Which current SCUM server versions and legitimate extension/log sources can produce player position and vehicle transitions without OCR or input automation?
|
||||
- Which skill/attribute and reward operations have a safe, documented, version-bound server-side adapter rather than legacy direct database mutation?
|
||||
- Should plugin bundles be compiled from TypeScript into the manifest package or loaded as signed static artifacts from the plugin registry? The implementation must choose one before frontend migration begins.
|
||||
@@ -0,0 +1,29 @@
|
||||
## Why
|
||||
|
||||
The five recent SCUM deliveries implemented most SCUM-specific domain services and React panels in `platform/` and `platform_web/`, leaving the SCUM plugin as a manifest and schema declaration. This makes the plugin non-portable, hard-codes SCUM into the platform host, and does not provide a real server-side adapter that can collect events or execute approved game operations.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Move SCUM-specific feature ownership for configuration, local game-player intelligence, controlled player state changes, gifts, and map trajectories into the SCUM plugin package and its Companion runtime.
|
||||
- Introduce a long-running, platform-authorized SCUM Companion adapter that receives only typed commands, emits only declared semantic events, and reports typed, idempotent results.
|
||||
- **BREAKING** Replace platform-owned SCUM panels and SCUM-specific API/domain endpoints with a plugin-page module mounted by the generic platform plugin host.
|
||||
- **BREAKING** Replace platform-owned SCUM projections and persistence with plugin-scoped local data accessed through generic platform isolation, audit, job, and storage primitives.
|
||||
- Preserve the existing platform responsibilities for authorization, server/tenant isolation, review and approval, durable job delivery, audit records, retention enforcement, and generic page hosting.
|
||||
- Treat current platform-side implementations as transitional control-plane behavior; do not claim an operation is available until the Companion has a verified executor or event producer.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `scum-plugin-feature-ownership`: Defines the required ownership boundary between the generic platform and the SCUM plugin, including plugin-page mounting and migration of the five SCUM feature areas.
|
||||
- `scum-companion-runtime-adapter`: Defines the safe, typed Companion command/event adapter needed for real SCUM operation execution and semantic event collection.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- None. The prior SCUM requirements currently exist only in completed change artifacts, not in the repository's canonical `openspec/specs/` tree; this change establishes their replacement canonical contract.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected roots: `plugins/examples/scum-server-plugin/`, `plugins/sdk/`, `platform/`, and `platform_web/`.
|
||||
- The SCUM Companion becomes the only place that translates approved typed operations into SCUM/RCON/legitimate-extension work and translates server signals into semantic events.
|
||||
- Existing SCUM-specific platform APIs, models, services, and hard-coded frontend panels will require a staged migration with compatibility checks; unrelated platform and plugin behavior remains out of scope.
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Companion dispatches only declared typed SCUM operations
|
||||
The SCUM Companion SHALL run a bounded authenticated command-dispatch loop and SHALL execute only command types declared by the installed SCUM plugin, validated against their payload schema, server binding, permission/approval result, and compatible SCUM capability/version. It SHALL return an idempotent typed result for every claimed command.
|
||||
|
||||
#### Scenario: Supported gift delivery command
|
||||
- **WHEN** the Companion claims a valid, unexpired `reward.deliver` command for a server version with a registered delivery handler
|
||||
- **THEN** it executes only that handler and completes the command with a typed delivered, failed, notification-failed, or unknown result
|
||||
|
||||
#### Scenario: Unsupported or malformed command
|
||||
- **WHEN** the Companion claims a command whose type, schema, capability, or version is not supported
|
||||
- **THEN** it does not invoke SCUM, RCON, a database, OCR, or desktop automation and completes the command with an explicit unsupported or validation failure result
|
||||
|
||||
### Requirement: Companion emits validated semantic SCUM events
|
||||
The SCUM Companion SHALL collect only declared allowed sources and upload contiguous semantic event batches through the platform's durable log channel. It SHALL validate required event fields before upload and SHALL not emit raw IP addresses, network fingerprints, host paths, credentials, database rows, screenshots, or raw RCON command text.
|
||||
|
||||
#### Scenario: Valid login event
|
||||
- **WHEN** a supported SCUM source produces a successful-login record containing the declared player identity and timestamp fields
|
||||
- **THEN** the Companion uploads a validated `scum.login` semantic event and the plugin can create or update the local game-player profile
|
||||
|
||||
#### Scenario: Unknown source format
|
||||
- **WHEN** a log or extension source does not match a supported parser version or lacks required fields
|
||||
- **THEN** the Companion records a bounded diagnostic and does not fabricate a semantic login, position, vehicle, or security event
|
||||
|
||||
### Requirement: Map event collection remains controlled
|
||||
The SCUM Companion SHALL emit `player.position`, `vehicle.position`, `player.vehicle.enter`, and `player.vehicle.leave` only from a verified legitimate server-side source declared by the plugin. The plugin SHALL apply its declared coordinate transform, sampling precision, and retention policy before exposing trajectory data.
|
||||
|
||||
#### Scenario: Position source is unavailable
|
||||
- **WHEN** no supported server-side source can provide a validated player or vehicle position
|
||||
- **THEN** the trajectory page reports collection unavailable and does not use OCR, screenshots, keyboard/mouse injection, client-screen reading, or inferred synthetic tracks
|
||||
|
||||
#### Scenario: Cross-server isolation
|
||||
- **WHEN** events are emitted for two bound SCUM servers
|
||||
- **THEN** the Companion tags each batch with its bound server identity and no trajectory, player, or vehicle data from one server is returned for the other
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: SCUM feature ownership is plugin-local
|
||||
The system SHALL place SCUM-specific configuration semantics, player/gift/map/state-patch behavior, schemas, validators, Companion handlers, and feature UI modules in the SCUM plugin package. The platform SHALL expose only generic authorization, isolation, audit, storage, queue, retention, and plugin-host primitives and SHALL NOT add new SCUM-named domain services, API handlers, or frontend panels.
|
||||
|
||||
#### Scenario: A new SCUM capability is added
|
||||
- **WHEN** a SCUM-specific configuration field, event type, command, or view is introduced
|
||||
- **THEN** its implementation and tests are added to the SCUM plugin package while the platform change, if any, is reusable by non-SCUM plugins
|
||||
|
||||
#### Scenario: Existing platform SCUM code is migrated
|
||||
- **WHEN** an existing SCUM service or panel is replaced by its plugin equivalent
|
||||
- **THEN** the platform retains only a generic primitive and no hard-coded `game.scum` branch or SCUM component import remains in the plugin host
|
||||
|
||||
### Requirement: Plugin-owned pages mount in the platform host
|
||||
The SCUM plugin SHALL declare versioned page-module entries and their required permissions/capabilities. The platform web host SHALL mount the declared module inside the existing authenticated themed shell and SHALL pass only server-scoped, permission-filtered host context.
|
||||
|
||||
#### Scenario: Authorized administrator opens a SCUM page
|
||||
- **WHEN** an administrator with the declared permission opens a SCUM plugin route for an assigned server
|
||||
- **THEN** the host loads the SCUM-declared page module with that server-scoped context and does not use a platform-owned SCUM page implementation
|
||||
|
||||
#### Scenario: Page module is unavailable or incompatible
|
||||
- **WHEN** the declared SCUM page bundle fails integrity/version/capability validation
|
||||
- **THEN** the host shows an unavailable-page state and does not fall back to a hard-coded SCUM panel
|
||||
|
||||
### Requirement: Feature availability requires a plugin implementation
|
||||
The system SHALL expose a SCUM feature as actionable only when the installed plugin declares the feature and its Companion reports a compatible handler or event producer for the bound server version. Transitional platform records MAY be displayed as migrated read-only history but SHALL NOT imply executable capability.
|
||||
|
||||
#### Scenario: Unsupported state patch adapter
|
||||
- **WHEN** the bound SCUM version has no verified `game-state.patch` handler
|
||||
- **THEN** the plugin disables the edit control and reports that the version is unsupported without queuing a generic command
|
||||
|
||||
#### Scenario: Historical records during migration
|
||||
- **WHEN** records created by the transitional platform implementation exist for a bound server
|
||||
- **THEN** the plugin can display them with migration provenance while new writes use the plugin-owned feature path
|
||||
@@ -0,0 +1,42 @@
|
||||
## 1. Establish generic extension primitives
|
||||
|
||||
- [ ] 1.1 Audit every SCUM-named platform API, model, service, route, and hard-coded frontend import introduced by the five transitional deliveries; document its plugin-owned replacement and migration dependency.
|
||||
- [ ] 1.2 Define and test generic plugin-scoped record/event storage, audit linkage, retention, and typed command-result primitives without SCUM field names.
|
||||
- [ ] 1.3 Extend the plugin manifest/SDK with versioned page-bundle entries, feature capability declarations, and Companion handler/event-producer availability reporting.
|
||||
- [ ] 1.4 Add generic platform authorization, server isolation, bundle integrity/version validation, and unavailable-feature behavior for those declarations.
|
||||
|
||||
## 2. Build the SCUM plugin module and page bundle
|
||||
|
||||
- [ ] 2.1 Create a SCUM plugin-owned feature module with contracts, API client, schemas, validators, and migration adapters for configuration, players, gifts, state patches, and trajectories.
|
||||
- [ ] 2.2 Move the file/config workbench into the plugin page bundle and replace the four example settings with versioned SCUM configuration-field catalogs and explanatory controls.
|
||||
- [ ] 2.3 Move player profile, login/session/risk, gift, controlled-state, and map UI components into the plugin bundle with server-scoped permission checks.
|
||||
- [ ] 2.4 Replace `platform_web` SCUM component imports and `game.scum` branches with generic manifest-driven plugin page mounting; add host and plugin UI tests.
|
||||
|
||||
## 3. Implement the long-running SCUM Companion runtime
|
||||
|
||||
- [ ] 3.1 Implement authenticated registration, bounded dispatch polling, acknowledgement, idempotent result completion, backoff, and typed diagnostics in the SCUM Companion.
|
||||
- [ ] 3.2 Add a handler registry that validates declared schema, bound server, approval, server version, capability discovery, expiry, and idempotency before invoking an adapter.
|
||||
- [ ] 3.3 Implement safe configuration read/patch and diagnostics adapters that use only platform-authorized channels and redact host paths, credentials, and raw command text.
|
||||
- [ ] 3.4 Add Companion integration tests for command claiming, duplicate delivery, cancellation/expiry, malformed payloads, unsupported versions, and redaction.
|
||||
|
||||
## 4. Add verified SCUM data collectors
|
||||
|
||||
- [ ] 4.1 Identify supported SCUM log or legitimate server-side extension sources for successful login/logout and implement versioned parsers that emit validated semantic events.
|
||||
- [ ] 4.2 Implement server-isolated, irreversible per-server network correlation inside the Companion when a supported source provides it; never upload or persist raw IP/fingerprint values.
|
||||
- [ ] 4.3 Identify a legitimate non-OCR/non-desktop-automation source for player position, vehicle position, and vehicle transitions; implement coordinate conversion, sampling, and retention according to the plugin declaration.
|
||||
- [ ] 4.4 Implement durable semantic-event batch upload with ordering, duplicate acknowledgement, parser fixtures, unknown-format diagnostics, and cross-server isolation tests.
|
||||
|
||||
## 5. Add version-gated SCUM operation adapters
|
||||
|
||||
- [ ] 5.1 Implement a version-discovered `game-state.patch` adapter for only documented supported skill/attribute fields, including precondition read, safe-window verification, read-after-write confirmation, and typed old/new/result audit data.
|
||||
- [ ] 5.2 Keep unsupported player state fields, versions, or unsafe windows disabled in the plugin UI and return explicit unsupported results from the Companion.
|
||||
- [ ] 5.3 Implement a `reward.deliver` adapter that freezes the approved revision, performs idempotent delivery, and reports delivered/failed/unknown without automatically retrying unknown results.
|
||||
- [ ] 5.4 Implement a separate `player.notify` adapter that never repeats item delivery after notification failure; verify server-scoped recipient identity and redact message transport details.
|
||||
- [ ] 5.5 Add isolated non-production end-to-end tests for every supported adapter and ensure no raw SQL, unrestricted RCON, OCR, screenshots, keyboard/mouse injection, or direct game database write path exists.
|
||||
|
||||
## 6. Migrate transitional platform behavior safely
|
||||
|
||||
- [ ] 6.1 Introduce feature/version flags and read-only migration adapters so existing platform records remain visible with provenance while plugin-owned records become authoritative per server.
|
||||
- [ ] 6.2 Verify plugin parity for configuration, player history, gifts, state-patch audits, and trajectories against controlled fixtures and an isolated Companion integration environment.
|
||||
- [ ] 6.3 Remove SCUM-named platform APIs, models, services, routes, and frontend components only after no callers remain and migration/rollback evidence is recorded.
|
||||
- [ ] 6.4 Run full platform, plugin, frontend, manifest, OpenSpec strict, structure, and isolated end-to-end verification; commit and push only the scoped migration files.
|
||||
Reference in New Issue
Block a user