#!/usr/bin/env python3 """Verify the MVP target player count server-stability QA gate is covered.""" from pathlib import Path ROOT = Path(__file__).resolve().parents[1] ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md" QA_DOC = ROOT / "Docs" / "QA" / "MvpQaGates.md" MVP_DEF = ROOT / "Docs" / "SixMonthMvpDefinition.md" LATENCY_DOC = ROOT / "Docs" / "Ops" / "MultiplayerLatencyTestPlan.md" SERVER_GATE = ROOT / "Scripts" / "verify_server_launch_gate.py" TWO_CLIENT_GATE = ROOT / "Scripts" / "verify_two_client_connection_gate.py" RECONNECT_GATE = ROOT / "Scripts" / "verify_reconnect_state_retention_qa_gate.py" LOG_GATE = ROOT / "Scripts" / "verify_critical_log_spam_qa_gate.py" LOG_SCANNER = ROOT / "Scripts" / "scan_critical_log_spam.py" REQUIRED = { QA_DOC: [ "## Target Player Count Server Stability", "minimum proof: 2 players connected to the same server", "target closed-test smoke group: 4 players on one server", "stretch test: 8 players", "UDP `7777` remains listening", ], MVP_DEF: [ "minimum proof: 2 players connected to the same server", "target closed-test smoke group: 4 players on one server", "stretch test: 8 players", ], LATENCY_DOC: [ "Connect two packaged Windows clients.", "Confirm both clients see the same world time and weather.", "Core interactions eventually reconcile", ], SERVER_GATE: [ "agrarian-game-server.service", "0.0.0.0:7777/udp", ], TWO_CLIENT_GATE: [ "## Two-Client Connection", "play.agrariangame.com:7777", ], RECONNECT_GATE: [ "## Reconnect State Retention", ], LOG_GATE: [ "## Thirty-Minute Critical Log Soak", ], LOG_SCANNER: [ "no critical log spam detected", ], ROADMAP: [ "[x] Server remains stable with target test player count.", ], } def main() -> None: missing: list[str] = [] for path, snippets in REQUIRED.items(): text = path.read_text(encoding="utf-8") for snippet in snippets: if snippet not in text: missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}") if missing: raise SystemExit("FAILED: " + "; ".join(missing)) print("OK: target player count server-stability QA gate is documented and tied to launch, connection, reconnect, and log-soak coverage.") if __name__ == "__main__": main()