13 KiB
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