feat: add controlled scum player state patches

This commit is contained in:
npc0-hue
2026-07-28 16:10:06 +08:00
parent 1e31a87888
commit f496fb12ec
25 changed files with 1017 additions and 48 deletions
@@ -0,0 +1,4 @@
schema: spec-driven
created: 2026-07-28
goal: Provide safe authorized SCUM player attribute updates through the declared
game-client bridge.
@@ -0,0 +1,3 @@
# add-scum-player-state-patch
SCUM player detail and approved version-scoped attribute patching
@@ -0,0 +1,42 @@
## Context
The prior `scum-game-player-intelligence` change owns server-local player identity, sessions, risk signals, and access control. The existing game-client bridge supplies declared commands, approval states, leases, audit references, and result fencing, but it does not itself constrain individual game-state fields or maintain a readable player-change history.
## Goals / Non-Goals
**Goals:**
- Permit only catalogued SCUM skills and character attributes for an explicitly declared server game version.
- Verify player/server ownership, current state version, companion availability, declared maintenance/online safety state, and platform-admin approval before dispatch.
- Record before/after value, reason, requester, approver, bridge command result, and read-after-write confirmation as an immutable patch audit.
- Prevent unknown versions, fields, out-of-range values, stale versions, unsafe execution windows, and unknown/failed execution from being represented as applied.
**Non-Goals:**
- SQL or database access, raw JSON/INI write APIs, host paths, direct Run/game connections, OCR/input automation, player identity/risk-signal edits, bans, gifts, or map trails.
## Decisions
1. **Catalog at the platform boundary.** `SCUMPlayerStateCatalog` maps a declared server game version to a small list of field keys and numeric ranges. No caller or plugin payload can introduce fields dynamically. The initial exact version is `0.9.700.90357` and supports `skills.running` and `attributes.strength` in range 010.
2. **Use a dedicated typed bridge operation.** The manifest declares only `game-state.patch`, with a schema requiring target player ID, game version, expected state version, safety-window token, reason, and a list of catalogued changes. The result carries a bounded per-field outcome and an immediate confirmed state version; it contains no raw storage/database material.
3. **Two-stage platform-admin approval.** A server-authorized requester creates a durable patch record in `pending-approval`. A platform admin approves it after revalidating authorization, catalog, snapshot version, and safety window. Approval queues the bridge command and remains auditable; a requester who is also platform admin still creates then approves the explicit record.
4. **Snapshot/state fencing and confirmation.** A current `player.state` snapshot is the source of before values and its `stateVersion` is copied into the requested patch. The companion must reject mismatches, apply only declared fields in a verified maintenance/offline safety window, then read state back before returning success. Platform marks a record `confirmed` only when each returned value exactly equals its requested value and the returned state version advances. Failed and unknown results stay readable terminal audit states.
5. **Ownership is revalidated at every transition.** Player record lookup checks server ownership before viewing, creating, approving, or reading a patch. The bridge command is scoped to the same server plugin and profile; the generic queue cannot be used as an alternate raw patch entry point because the dedicated service owns field/snapshot validation and records the audit before dispatch.
## Risks / Trade-offs
- [Companion has no exact version/state snapshot] → Disable the form and return a readable unsupported/unknown-version result.
- [State changes between snapshot and execution] → The expected state version causes the companion to reject; record the conflict without claiming application.
- [Companion times out or result is missing] → Keep the record `execution-unknown`; do not infer a write, and require a later confirmation read.
- [Maintenance state becomes unsafe] → Approval and companion both reject dispatch; no write is attempted.
## Migration Plan
1. Add model-first patch records, memory/file/MySQL repositories, and immutable transition helpers.
2. Deploy the manifest schemas and companion version declaration; no version is implicitly supported.
3. Deploy the API and console. Existing player profiles retain all read-only intelligence behavior.
4. Roll back by disabling the command declaration and form; historical audit records remain readable.
@@ -0,0 +1,22 @@
## Why
SCUM player intelligence currently presents useful local identity and risk context, but administrators cannot safely correct the limited in-game state that the installed server version explicitly supports. A controlled patch workflow is required so changes remain reviewable, version-fenced, approved, and executed only through the companion command channel.
## What Changes
- Add a SCUM version-scoped player-state field catalog for supported skills and character attributes only.
- Add player-state read snapshots and an approved `game-state.patch` bridge operation with optimistic state-version checks, safe execution-window checks, and confirmation reads.
- Persist an immutable patch audit record containing requested old/new values, reason, requester/approver, command result, and confirmation status.
- Add authorized API contracts and Chinese console controls that show the editable diff, approval state, readable outcome, and player context.
## Capabilities
### New Capabilities
- `scum-player-state-patch`: Version-fenced, approved SCUM player skill and character-attribute changes via the game-client bridge.
## Impact
- Affects Platform player domain/models/repositories/services/validation/API and durable metadata storage.
- Extends the SCUM manifest with a bounded patch command and typed schemas, plus Platform Web contracts and console records.
- Does not permit SQL, raw configuration/JSON/INI writing, direct game database access, unbounded state editing, automatic moderation, gifts, or map trails.
@@ -0,0 +1,48 @@
## ADDED Requirements
### Requirement: Version-scoped player state catalog
The system SHALL allow SCUM player state patches only for a declared exact game version and an explicit catalog of skill/attribute fields with numeric ranges.
#### Scenario: Unknown server version
- **WHEN** an administrator requests a patch and the current server state reports an unknown game version
- **THEN** the system SHALL disable the patch request and SHALL not queue a bridge command
#### Scenario: Out-of-range or unknown field
- **WHEN** a request contains a field absent from the version catalog or a value outside its range
- **THEN** the system SHALL reject the request before an audit approval or game-side command is created
### Requirement: Authorized and safe patch request
The system SHALL ensure that the game player belongs to the target server, the requester has server access, the expected player-state version matches the current snapshot, and the snapshot declares a verified maintenance/offline safety window before creating a patch record.
#### Scenario: Stale player state
- **WHEN** a patch carries an expected state version different from the current player-state snapshot
- **THEN** the system SHALL reject it as a conflict and SHALL not dispatch a patch command
#### Scenario: Online server without a safe window
- **WHEN** a state snapshot indicates the target player is online or maintenance is not verified
- **THEN** the system SHALL reject the request with a readable safety status
### Requirement: Explicit administrator approval and immutable audit
The system SHALL persist each accepted request with field-level before/after values, reason, requester, approval state, approver, and execution status. Only a platform administrator with server access MAY approve dispatch.
#### Scenario: Non-admin approval
- **WHEN** a server-authorized non-platform-admin attempts to approve a pending patch
- **THEN** the system SHALL deny approval and SHALL leave the patch pending
### Requirement: Typed game-state patch execution and confirmation
The system SHALL dispatch only the declared `game-state.patch` command through the game-client bridge. A successful record SHALL require a typed per-field result and a read-after-write confirmation whose values equal the requested values and whose state version advances.
#### Scenario: Companion reports a failure
- **WHEN** the companion returns a failed patch command result
- **THEN** the patch record SHALL be terminal `execution-failed`, preserve the readable result summary, and SHALL not be reported as applied
#### Scenario: Result is missing or unconfirmable
- **WHEN** the command expires, is cancelled, returns malformed state, or cannot confirm the requested values
- **THEN** the record SHALL retain an explicit `execution-unknown` or `confirmation-failed` status and SHALL not be reported as applied
### Requirement: Readable SCUM console workflow
The SCUM player console SHALL show player detail context and provide a Chinese patch form only for supported safe states. It SHALL show a textual field diff, reason, approval status, executor result, and confirmation status without relying only on color.
#### Scenario: Pending approval
- **WHEN** a patch is awaiting approval
- **THEN** the console SHALL label it as awaiting platform-administrator approval and display the old/new values and requester reason
@@ -0,0 +1,21 @@
## 1. Contracts, models, and persistence
- [x] 1.1 Add version-scoped SCUM state catalog, player-state snapshot/patch domain types, audit model/repositories/migration/store implementations, and field/safety validation.
- [x] 1.2 Add service state machine for request, platform-admin approval, bridge-result reconciliation, and confirmation-read semantics with immutable audit evidence.
- [x] 1.3 Add focused backend tests for unknown version, invalid field/range, server ownership, stale version, unsafe window, approval permission, execution failure/unknown, audit, and confirmation.
## 2. API and SCUM bridge contract
- [x] 2.1 Add named DTOs and authorized player-state/patch API routes and tests.
- [x] 2.2 Declare `game-state.patch` and player-state schemas in the SCUM manifest, extend companion bridge validation fixtures/tests, and preserve the typed bounded command channel.
## 3. SCUM console
- [x] 3.1 Add frontend API/types and Chinese player-detail patch controls using shared console/theme primitives.
- [x] 3.2 Render readable diff, reason, approval, execution, and confirmation histories; disable unsupported or unsafe writes.
- [x] 3.3 Add frontend tests for field labels, diff/audit readability, and disabled safety states.
## 4. Verification
- [x] 4.1 Run strict OpenSpec validation, focused backend/plugin/frontend tests, and `scripts/check-structure.sh`.
- [ ] 4.2 Stage only this task's files, commit on `main`, and push the configured remote.