5 Commits
Author SHA1 Message Date
Дмитрий 5343020bed feat(portable): MR2 Wildcard portable character vertical slice
- Enforce fail-closed backend resolution in LocalBackend::info (unknown ruleset = error).
- Implement strict three-space isolation (Wildcard != CoA != Reborn) across canonical store, host mappings, and collections.
- Isolate collection namespaces (wildcard:appearance, wildcard:vanity) and reject cross-ruleset collections in claim and import.
- Enforce Control Protocol v2 ruleset verification on TransferOffer, TransferCommit, and Claimed response.
- Route Direct Ingress and Relay Link dynamically according to realm world port (8085 for CoA, 8086 for Wildcard).
- Add runtime session attack rejection test suite (cross-ruleset session offers, checkpoints, owner acks, server IDs).
- Verify end-to-end Wildcard session lifecycle and documentation updates.
2026-10-22 17:24:15 +05:00
ДмитрийandClaude Sonnet 5.5 35a2d5dea7 feat(portable): Phase 6.1 format v2 with strict v1 migration and job format; Phase 7 capability negotiation and extensions
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 06:54:11 +05:00
ДмитрийandClaude Sonnet 5.5 e8f99c16b7 feat(portable): offline importer into a stopped realm, with journaled recovery (Phase 3)
Imports a canonical snapshot into a stopped disposable realm through the existing
Db abstraction, in one MySQL transaction: guids allocated inside the transaction
from the realm's own tables and every reference remapped, orphan cleanup, name
and start-position handling, self-asserting result, and a marker row. Untrusted
strings and blobs reach SQL only as hex literals from a typed encoder.

Manager mappings are recorded only after the realm commit, in one local
transaction; an import journal (schema 3) plus the marker recover a crash
between the two commits. Preflight refuses wrong ruleset, running realm,
missing account/content and more before anything is written.

Stock character_talent rows are never written: a real worldserver asserts on a
non-talent row. Item identity no longer includes the crafter (v2).

Production import remains the designed in-core PortableImportService
(docs/PORTABLE_IMPORT_SERVICE.md); nothing of it is implemented.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 09:02:21 +05:00
ДмитрийandClaude Sonnet 5.5 c590b82d27 feat(portable): read-only export of offline characters from a realm (Phase 2)
Reads one offline character out of a realm's characters database through the
existing Db abstraction: fixed SQL with the local guid as the only (numeric)
input, one consistent READ ONLY snapshot per character, hex-encoded text.
Maps the approved minimal v1 scope to the portable model; refuses online,
deleted, bot, active challenge/game mode/Manastorm and unknown-table cases.
Adds the 163-table registry, the settings policy, "Make Portable" in one store
transaction, and item mapping lifecycle with content identity (schema 2) so a
recycled local item guid never inherits an old portable item.

Recorded answers of a real MySQL drive the unit tests; live tests re-verify
them, read-only enforcement and snapshot consistency on a disposable server.
No realm database is written and nothing changes for existing installs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 08:11:54 +05:00
ДмитрийandClaude Sonnet 5.5 efd4b8bbf2 feat(portable): local canonical storage for portable characters (Phase 1)
Adds crates/coa-core/src/portable: UUIDv7 identities, namespaced content ids,
the v1 portable character model (validated, bounded, canonical), compressed
hashed snapshots, a union-only collection set, and a SQLite (WAL) store with
revisions, stale-revision rejection, rollback-as-new-revision, configurable
history, realm/item mappings and forward-only migrations.

No realm database, network or UI is touched; no existing behaviour changes.
45 new tests. Format documented in docs/PORTABLE_FORMAT.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 07:13:14 +05:00