Persistence and migration rules for AI
🤖 AI-critical ✅ Political World source-backed
Persistence is an area where plausible-looking AI code can quietly damage saves.
Use stricter rules than for ordinary runtime helpers.
Rule 1 — public storage API first
Section titled “Rule 1 — public storage API first”For a Political World addon, prefer:
Get/SetKingdomIntGet/SetKingdomStringGet/SetKingdomBoolGet/SetKingdomFloataddon-private tagsparty-private typed dataDo not reconstruct internal:
pw_api2_data_...ukiol_api_data_...__private_tagskeys in normal addon code.
Those formats are documented for research/migration understanding, not as the supported addon contract.
Rule 2 — do not claim save persistence from source naming alone
Section titled “Rule 2 — do not claim save persistence from source naming alone”A folder named:
Persistenceor a method that writes Kingdom.data is evidence of persistence intent.
It is not by itself a completed:
save → process restart → loadruntime verification.
When no round-trip result exists, say:
source-verified storage path; runtime persistence test pendingRule 3 — stable IDs are data
Section titled “Rule 3 — stable IDs are data”Never rename a persistent ID only to match:
- new author name;
- new namespace;
- cleaner style;
- project rebranding.
First identify migration consequences.
Political World intentionally retains ukiol_* IDs while its public project identity is Lous12.PoliticalWorld.
Rule 4 — new and legacy evidence can coexist
Section titled “Rule 4 — new and legacy evidence can coexist”If code can read:
v2 keyfallback old v1 keydo not “clean up” the old path unless the migration policy explicitly permits removal.
Backward compatibility code can look redundant while being essential.
Rule 5 — copy-forward before destructive migration
Section titled “Rule 5 — copy-forward before destructive migration”Safe default for an existing key migration:
read newif missing: read legacy if found: write new keep legacyDo not delete old data in generated migration code unless rollback/compatibility requirements have been considered.
Rule 6 — private by default
Section titled “Rule 6 — private by default”If state is only for one addon:
addon-private data/tagnot a shared tag/key.
Shared string conventions are an API between mods and must be documented as such.
Rule 7 — typed helpers preserve semantics
Section titled “Rule 7 — typed helpers preserve semantics”Use:
SetKingdomBoolSetKingdomFloatinstead of manually encoding bool/float through strings.
The framework already defines representation and culture behavior.
Rule 8 — party state follows stable party ID
Section titled “Rule 8 — party state follows stable party ID”Do not attach party data to:
list indexdisplay namecurrent orderwhen a stable party ID exists.
Rule 9 — never invent a migration result
Section titled “Rule 9 — never invent a migration result”If the actual save/load probe has not been executed, do not write:
"verified to persist"Use the documented status.
Rule 10 — version-bind persistence claims
Section titled “Rule 10 — version-bind persistence claims”A persistence result must identify:
WorldBoxNeoModLoaderparent mod/APIprobe versionSave behavior is too important to leave versionless.
Rule 11 — do not widen a probe beyond its tested transition
Section titled “Rule 11 — do not widen a probe beyond its tested transition”A two-save same-process isolation result does not automatically prove full-restart isolation, party storage, or future versions.
Keep independent claims independent until a probe explicitly joins them.
Current verified Lab records
Section titled “Current verified Lab records”WBML-0001 has now promoted one claim to runtime Verified:
WorldBox 0.51.2 build 719NeoModLoader 1.2.0.1PoliticalWorldAPI 1.14.0Verified after a full process restart:
kingdom intkingdom Unicode stringkingdom boolkingdom floataddon-private kingdom tagshared kingdom tagDo not extend WBML-0001 to party-private data, other versions, or legacy migration without separate evidence.
WBML-0002 separately verified, on the same WorldBox/NML/API stack, a two-save same-process sequence:
A → B → A → Bfor marker + kingdom int/string/bool/float + addon-private/shared kingdom tags. Each world rejected the other world’s current-run signature and recovered its own values.
Do not rewrite this as full-process-restart isolation or party-private isolation; those are wider claims.