--- /SHiREVault/Backup/OSBackups/SHIRE-ACADEMY-ROUND3-TIMEOUT-CONTRACT-REPAIR-20260805T123006Z/before/design_academy_round3_timeout_selftest.py 2026-08-05 20:30:05.995778000 +0800 +++ /SHiREVault/Backup/OSBackups/SHIRE-ACADEMY-ROUND3-TIMEOUT-CONTRACT-REPAIR-20260805T123006Z/staged/design_academy_round3_timeout_selftest.py 2026-08-05 20:30:07.472489500 +0800 @@ -5,10 +5,20 @@ import hashlib import json import socket +import sys import urllib.error from pathlib import Path ROOT = Path(__file__).resolve().parent.parent + +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +from services.design_academy_practice_service import ( + AcademyBrainResponseError, + practice_service, +) + BRAIN = ROOT / "ai" / "brain_server.py" SERVICE = ROOT / "services" / "design_academy_practice_service.py" @@ -94,6 +104,39 @@ assert service_ns["_academy_client_timeout_for_round"](2) == 300 assert service_ns["_academy_client_timeout_for_round"](3) == 420 +timeout_failure = AcademyBrainResponseError( + "Brain API HTTP 504: Academy model request timed out", + { + "retryable": True, + "infrastructure_failure": True, + "timeout_stage": "ollama_generation", + }, +) + +assert ( + practice_service._transient_brain_failure( + timeout_failure + ) + is True +) + +contract_failure = AcademyBrainResponseError( + "Brain API HTTP 422: Academy structured output invalid", + { + "retryable": False, + "infrastructure_failure": False, + "content_format_failure": True, + "failure_class": "academy_output_contract_failure", + }, +) + +assert ( + practice_service._transient_brain_failure( + contract_failure + ) + is False +) + required_brain_tokens = [ 'ACADEMY_OUTPUT_CONTRACT = "academy_round_json_v6"', 'os.environ.get("SHIRE_ACADEMY_ROUND3_TIMEOUT", "360")', @@ -110,7 +153,9 @@ 'ACADEMY_ROUND3_CLIENT_TIMEOUT = 420', 'timeout=_academy_client_timeout_for_round(round_number)', '"practice_round3_client_timeout_seconds": ACADEMY_ROUND3_CLIENT_TIMEOUT', - '"http 504"', + 'payload.get("infrastructure_failure") is True', + 'return payload.get("retryable") is True', + '"brain api practice request failed"', 'if payload.get("output_contract") != "academy_round_json_v6"', 'if payload.get("context_profile") != "academy_round_specific_v5"', ] @@ -138,6 +183,8 @@ "structured_timeout_http_status": 504, "structured_timeout_retryable": True, "structured_timeout_infrastructure_failure": True, + "structured_timeout_classifier_verified": True, + "contract_failure_not_classified_as_timeout": True, "empty_raw_answer_sha256_audited": True, "round3_schema_preserved": True, "round2_completeness_guard_preserved": True,