chore(db): switch meta.schema_version to monotonic semver (#888)

Replace SHA-1 hash in meta.schema_version with an orderable semver
string ("1.0.0"). SHA preserved in new schema_sha column for tamper
detection. Enables savegame migration lineage in Phase 5+ — saves can
record their schema version and determine which migrations to apply.

Updated both generators, check-systems-db-stamp validation (rejects
old SHA-hex values), schema DDL, and asset-pipeline docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-02 10:09:13 +02:00
co-authored by Claude Opus 4.6
parent ffa638a46c
commit 5aa998cb86
6 changed files with 76 additions and 18 deletions
+14 -3
View File
@@ -92,6 +92,11 @@ _ATLAS_SCHEMA_END_MARKER = "-- END ATLAS INDEX"
# Generator metadata stamp (#855, #856)
# ---------------------------------------------------------------------------
# Monotonic schema version — shared constant with import_economics.py (#888).
# Bump manually on any backwards-incompatible schema change.
SCHEMA_VERSION = "1.0.0"
def _file_sha1(*paths: Path) -> str:
"""Return SHA-1 hex of the concatenated content of one or more files.
@@ -124,9 +129,9 @@ def _write_stamp(conn: sqlite3.Connection) -> None:
generator_sha = _file_sha1(Path(__file__))
conn.execute(
"""INSERT OR REPLACE INTO meta
(generator_name, schema_version, generator_sha, generated_at)
VALUES ('generate_atlas', ?, ?, datetime('now'))""",
(schema_sha, generator_sha),
(generator_name, schema_version, schema_sha, generator_sha, generated_at)
VALUES ('generate_atlas', ?, ?, ?, datetime('now'))""",
(SCHEMA_VERSION, schema_sha, generator_sha),
)
@@ -172,11 +177,17 @@ def ensure_atlas_schema(conn: sqlite3.Connection) -> None:
CREATE TABLE IF NOT EXISTS meta (
generator_name TEXT PRIMARY KEY,
schema_version TEXT NOT NULL,
schema_sha TEXT,
generator_sha TEXT NOT NULL,
generated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
"""
)
# Add schema_sha column to existing DBs that pre-date #888 (#888 migration).
try:
conn.execute("ALTER TABLE meta ADD COLUMN schema_sha TEXT")
except Exception:
pass # column already exists
def _first_int(values, default: int = 0) -> int: