175 lines
13 KiB
Markdown
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
|