Files

175 lines
13 KiB
Markdown

## ADDED Requirements
### Requirement: Current-service schema compatibility gate
The system SHALL enable each SCUM database-backed capability only after the bound Run has performed a read-only probe against the current server database and the result matches a versioned plugin schema adapter for that capability.
#### Scenario: Supported current schema is detected
- **WHEN** the bound Run reports a schema fingerprint whose required tables, columns, types, joins, and cardinality match the plugin adapter for player reads
- **THEN** Platform enables the player-read capability for that server and records the adapter version, fingerprint, probe time, and safe capability result
#### Scenario: A current binding has no valid probe evidence
- **WHEN** a compatible Run binding becomes ready, reconnects, or reports a changed database/plugin identity without current probe evidence
- **THEN** Platform automatically schedules the bounded read-only probe before any affected query or write and exposes no browser action for starting it
#### Scenario: Generic probe execution is unavailable
- **WHEN** the bound Run lacks the required generic diagnostic-probe contract
- **THEN** database-backed SCUM capabilities remain disabled with a safe connection/capability reason and SHALL NOT fall back to a copied database, cached schema, reference model, or guessed query
#### Scenario: One world-data requirement is incompatible
- **WHEN** a required vehicle column is missing, has an incompatible type, or the declared join is not unique while player and squad requirements still match
- **THEN** Platform disables only the affected vehicle capability and SHALL NOT treat an empty vehicle list as a successful current-server result
#### Scenario: Compatibility evidence becomes invalid
- **WHEN** the game version, database instance identity, Run binding, plugin adapter version, or schema fingerprint changes
- **THEN** Platform invalidates the affected capability evidence and requires a new successful probe before another query or write uses that evidence
#### Scenario: Probe result is exposed safely
- **WHEN** Platform stores or returns schema compatibility status
- **THEN** the result excludes the database path, DSN, socket, credentials, raw SQL, raw row content, and host identity
#### Scenario: Run snapshots the active database for a safe read
- **WHEN** Run must use an execution-time read-only snapshot to avoid locking the active SQLite database
- **THEN** the snapshot is bound to the current server/Run/database identity, timestamped, checksummed, short-lived, and rejected after rebinding or source-identity change
### Requirement: Plugin-owned immutable parser and query assets
The SCUM plugin SHALL own versioned login parsers, SQLite query assets, and parameter/result schemas, and each executable data asset SHALL be referenced by an integrity digest in the plugin manifest and generated Run package.
#### Scenario: Declared query is dispatched
- **WHEN** Platform schedules the declared player query with schema-valid bounded parameters
- **THEN** Run executes the matching packaged asset only after the plugin ID, version, template key, server binding, and asset digest all match
#### Scenario: Caller supplies arbitrary query material
- **WHEN** a browser, AI request, Platform API caller, or job payload supplies raw SQL, an unknown template key, extra parameters, or a different asset digest
- **THEN** the request is rejected before SQLite execution and no protected query content is stored in a browser-visible response
#### Scenario: SCUM behavior is absent from Run
- **WHEN** Run selects an executor for a SCUM plugin query
- **THEN** it uses generic SQLite and packaged-asset contracts and contains no branch keyed by SCUM, a `scum.*` template name, a SCUM table, or a SCUM command
### Requirement: Bounded and correlated SQLite reads
Run SHALL execute plugin query assets with bound parameters and query-only restrictions, and Platform SHALL correlate every result to its original durable job before validating and storing it.
#### Scenario: Query violates the read boundary
- **WHEN** an asset or parameter expansion attempts multiple statements, DDL, mutation, `ATTACH`, extension loading, a write PRAGMA, or string-concatenated parameter injection
- **THEN** Run rejects execution with a stable safe error and returns no rows
#### Scenario: Query exceeds a declared bound
- **WHEN** execution times out, the database remains locked, or rows/result bytes exceed the template limits
- **THEN** Run stops the read and returns a bounded safe error without converting the failure into an empty successful result
#### Scenario: Fast, duplicate, or late result arrives
- **WHEN** a result arrives immediately, is delivered more than once, or arrives after a newer scan
- **THEN** the pre-existing job correlation prevents loss or cross-server association, duplicate delivery is idempotent, and an older result cannot replace a newer completed generation
#### Scenario: Result envelope is malformed
- **WHEN** the server/plugin binding, template key, schema version, asset digest, checksum, observed time, or row schema does not match the queued job
- **THEN** Platform rejects the result before any local SCUM record changes
### Requirement: Authentic login-driven player and session records
The system SHALL parse the plugin-declared current SCUM login/logout format and atomically maintain a player and session uniquely scoped by server instance and external player identifier.
#### Scenario: Parser version is enabled
- **WHEN** a plugin login parser is registered for a SCUM/game version
- **THEN** sanitized fixtures captured from the active service prove its successful login/logout mapping and parser digest before it can create durable players
#### Scenario: Unknown player logs in successfully
- **WHEN** an authentic successful login event contains a valid external player ID, display name, event identity, and occurrence time
- **THEN** Platform atomically creates or updates exactly one `(server_instance_id, external_player_id)` player and opens one matching local session
#### Scenario: Concurrent first-login delivery occurs
- **WHEN** two workers process the same new player's first successful login concurrently
- **THEN** a database unique constraint and idempotent event identity produce one player and one session without a duplicate-key user-visible failure
#### Scenario: Duplicate or older event arrives
- **WHEN** an acknowledged login/logout event is replayed or an older logout arrives after a later login
- **THEN** Platform creates no duplicate session and does not regress the player's current display name, last-seen time, or newer online session
#### Scenario: Source format has no native session identifier
- **WHEN** a valid login line has a transport cursor and player identity but no game-provided event/session ID
- **THEN** Platform derives a privacy-safe logical event fingerprint and deterministic server-scoped session identity from normalized non-network event fields, independent of stream generation, so replaying that logical line cannot create a second session
#### Scenario: Line is malformed or login did not succeed
- **WHEN** a partial, malformed, undecodable, or oversized line, failed authentication attempt, disconnect without a matching identity, or unrelated log message is received
- **THEN** the parser emits no successful-login event and Platform creates no player or fabricated session
#### Scenario: Logout has no matching session
- **WHEN** a valid logout event has no matching open session under the same server/player/source epoch
- **THEN** Platform records no fabricated login session and does not close a different or newer session
#### Scenario: Network material is present
- **WHEN** the source login line includes an IP address or another network identifier
- **THEN** raw network material is discarded before durable player/session storage and is absent from SCUM APIs
#### Scenario: Database save time changes
- **WHEN** a SCUM.db row reports `last_login_time`, `last_save_time`, or another persistence timestamp without a corresponding current login session event
- **THEN** Platform SHALL NOT mark the player online from that database timestamp alone
### Requirement: Login stream continuity and binding fences
The login source SHALL keep transport cursor identity separate from stable logical event identity and preserve current-binding isolation across batch replay, file rotation/truncation, Run restart, reconnect, and partial-line boundaries.
#### Scenario: Log file rotates or truncates
- **WHEN** the declared login file is replaced, rotated, or truncated
- **THEN** Run starts a new durable transport generation and resumes only at a complete-line boundary while any overlapped logical event retains the same privacy-safe fingerprint
#### Scenario: Rotation overlap replays an acknowledged login
- **WHEN** a previously acknowledged logical login line is observed again under a new stream generation during copy-truncate or rotation overlap
- **THEN** the new transport event is acknowledged idempotently and Platform creates no second player or session
#### Scenario: Run restarts with an acknowledged cursor
- **WHEN** Run restarts or reconnects after Platform acknowledged a source sequence
- **THEN** replay begins from a safe acknowledged boundary and duplicate batches remain idempotent
#### Scenario: Event belongs to an obsolete binding
- **WHEN** a typed login/logout event carries a Run binding, server instance, plugin version, stream generation, or source identity that no longer matches the active binding
- **THEN** Platform rejects it before changing a player or session
#### Scenario: Online session loses authoritative log continuity
- **WHEN** the binding is replaced, the server stops, or log continuity is lost without a matching logout event
- **THEN** Platform closes or marks the affected session unknown with a bounded terminal reason and SHALL NOT continue presenting it as a confirmed current login
### Requirement: Automatic server-bound synchronization
The system SHALL synchronize verified SCUM.db resources automatically when a compatible Run binding becomes ready and at plugin-declared bounded cadences, without a user-facing manual data-refresh operation.
#### Scenario: Compatible Run becomes ready
- **WHEN** a server obtains a current Run binding and successful capability probe
- **THEN** Platform schedules an initial bounded scan and later jittered resource scans within per-server concurrency limits
#### Scenario: New login needs enrichment
- **WHEN** login ingestion creates a player whose database details are not yet known
- **THEN** Platform may schedule a bounded player-detail lookup without delaying player creation or filling unknown values with defaults
#### Scenario: Page is opened
- **WHEN** an operator opens users, squads, map, or gifts
- **THEN** the page reads the platform-local data API and SHALL NOT dispatch a Run query, schema probe, projection refresh, audit, or synchronization command
#### Scenario: A later scan fails
- **WHEN** a resource previously synchronized successfully and a later scan fails or is partial
- **THEN** Platform retains the last completed local generation, records the safe connection/sync failure internally, and does not delete rows or present generated replacements
#### Scenario: Resource synchronization status is requested
- **WHEN** a local resource API reports its availability
- **THEN** it distinguishes not-yet-synchronized, successfully-synchronized-empty, schema-incompatible, current/last-complete data, and connection/read failure with concrete collection time and a safe reason
#### Scenario: No completed local generation exists
- **WHEN** a current scan has not completed successfully
- **THEN** Platform returns the appropriate unavailable/not-yet-synchronized state and SHALL NOT fall back to a legacy projection, sample record, reference database, cached unbound row, or fabricated empty success
### Requirement: Dedicated local SCUM database records
The system SHALL persist SCUM identities, sessions, details, squads, squad members, vehicles, flags, positions, gifts, deliveries, and sync cursors in dedicated queryable local stores rather than in SCUM projection/Workflow snapshot fields.
#### Scenario: File storage backend is active
- **WHEN** Platform runs with the default file metadata backend
- **THEN** SCUM records use a platform-owned local database under the configured data directory and a position update does not rewrite the global metadata snapshot
#### Scenario: MySQL storage backend is active
- **WHEN** Platform runs with the MySQL backend
- **THEN** explicit migrations create normalized SCUM tables with server-scoped indexes and uniqueness constraints instead of storing SCUM collections only inside `platform_metadata_snapshots.snapshot_json`
#### Scenario: Source omits a numeric fact
- **WHEN** a verified row omits fame, currency, a coordinate, an owner, or another fact
- **THEN** the corresponding local field remains null/absent and SHALL NOT be set to zero, an inferred owner, a generated coordinate, or an unrelated identifier
#### Scenario: Full scan completes
- **WHEN** every page of a bounded full resource scan passes schema and checksum validation
- **THEN** Platform transactionally commits that generation and may mark records absent only from that completed generation