diff --git a/runtime/history/NEWFI-260907-PORTAL200-APPLY3FAILRCA1.json b/runtime/history/NEWFI-260907-PORTAL200-APPLY3FAILRCA1.json new file mode 100644 index 00000000..539a1893 --- /dev/null +++ b/runtime/history/NEWFI-260907-PORTAL200-APPLY3FAILRCA1.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "NEWFI-260907-PORTAL200-APPLY3FAILRCA1", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "read-only", + "component": "newfi-portal200-apply3-failure-contract-rca", + "started_at_utc": "2026-09-07T11:31:38Z", + "finished_at_utc": "2026-09-07T11:31:38Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "01c670ca07e27a1cb55525fe1ea9c027122da3bc03abe444f5de750d8c345a62", + "duplicate_failed_command_blocked": false, + "block_reason": null, + "execution_started": true, + "change_declared": false, + "result_contract_valid": true, + "result_contract_status": null, + "result_contract_error": null, + "command_rc": 0, + "changes_made": false, + "rollback_started": false, + "rollback_restored": null, + "mutation_outcome": "NO_MUTATION", + "sanitized": true, + "secrets_included": false, + "private_addresses_included": false, + "raw_evidence_retained_locally": true, + "raw_evidence_sha256": "b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12", + "sanitized_output_sha256": "b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "NEWFI56_BEGIN\nCOMMAND_ID=NEWFI-260907-PORTAL200-APPLY3FAILRCA1\nMUTATION_SCOPE=NONE_READ_ONLY\nWRAPPER_BYTES=669\nWRAPPER_SHA256=dec036ea985e75d776b2de8c2bede77fe4b4aafa5da33648b2a6b5f79f3dec30\nAPPLY3_SELECTED_OUTPUT_BEGIN\nAPPLY3_SELECTED_OUTPUT_END\nAPPLY3_SELECTED_LINE_COUNT=0\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nRUNNER_BYTES=21321\nRUNNER_CONTRACT_VALIDATOR_SOURCE_BEGIN\n{\"line\":12,\"text\":\"command_rc = int(command_rc)\"}\n{\"line\":13,\"text\":\"\"}\n{\"line\":14,\"text\":\"result = {\"}\n{\"line\":15,\"text\":\" \\\"valid\\\": True,\"}\n{\"line\":16,\"text\":\" \\\"status\\\": \\\"NOT_APPLICABLE\\\",\"}\n{\"line\":17,\"text\":\" \\\"changes_made\\\": \\\"false\\\",\"}\n{\"line\":18,\"text\":\" \\\"rollback_started\\\": \\\"false\\\",\"}\n{\"line\":19,\"text\":\" \\\"rollback_restored\\\": \\\"null\\\",\"}\n{\"line\":20,\"text\":\" \\\"mutation_outcome\\\": \\\"NO_MUTATION\\\",\"}\n{\"line\":21,\"text\":\" \\\"error\\\": \\\"NONE\\\",\"}\n{\"line\":22,\"text\":\"}\"}\n{\"line\":23,\"text\":\"\"}\n{\"line\":24,\"text\":\"if mode == \\\"change\\\":\"}\n{\"line\":25,\"text\":\" result = {\"}\n{\"line\":26,\"text\":\" \\\"valid\\\": False,\"}\n{\"line\":27,\"text\":\" \\\"status\\\": \\\"UNKNOWN\\\",\"}\n{\"line\":28,\"text\":\" \\\"changes_made\\\": \\\"unknown\\\",\"}\n{\"line\":29,\"text\":\" \\\"rollback_started\\\": \\\"unknown\\\",\"}\n{\"line\":30,\"text\":\" \\\"rollback_restored\\\": \\\"null\\\",\"}\n{\"line\":31,\"text\":\" \\\"mutation_outcome\\\": \\\"UNKNOWN\\\",\"}\n{\"line\":32,\"text\":\" \\\"error\\\": \\\"MISSING_CONTRACT\\\",\"}\n{\"line\":33,\"text\":\" }\"}\n{\"line\":34,\"text\":\" marker = \\\"HOMELAB_RESULT_CONTRACT=\\\"\"}\n{\"line\":35,\"text\":\" lines = Path(raw_path).read_bytes().decode(\"}\n{\"line\":36,\"text\":\" \\\"utf-8\\\",\"}\n{\"line\":37,\"text\":\" errors=\\\"replace\\\",\"}\n{\"line\":38,\"text\":\" ).splitlines()\"}\n{\"line\":39,\"text\":\" payloads = [\"}\n{\"line\":43,\"text\":\" ]\"}\n{\"line\":44,\"text\":\" if len(payloads) == 1:\"}\n{\"line\":45,\"text\":\" try:\"}\n{\"line\":46,\"text\":\" document = json.loads(payloads[0])\"}\n{\"line\":47,\"text\":\" if not isinstance(document, dict):\"}\n{\"line\":48,\"text\":\" raise ValueError(\\\"contract root is not object\\\")\"}\n{\"line\":49,\"text\":\" if document.get(\\\"version\\\") != 1:\"}\n{\"line\":50,\"text\":\" raise ValueError(\\\"unsupported version\\\")\"}\n{\"line\":51,\"text\":\" if document.get(\\\"command_id\\\") != command_id:\"}\n{\"line\":52,\"text\":\" raise ValueError(\\\"command_id mismatch\\\")\"}\n{\"line\":53,\"text\":\" status = document.get(\\\"status\\\")\"}\n{\"line\":54,\"text\":\" if status not in {\\\"OK\\\", \\\"BLOCKED\\\", \\\"FAIL\\\"}:\"}\n{\"line\":55,\"text\":\" raise ValueError(\\\"invalid status\\\")\"}\n{\"line\":56,\"text\":\" changes = document.get(\\\"changes_made\\\")\"}\n{\"line\":57,\"text\":\" rollback_started = document.get(\\\"rollback_started\\\")\"}\n{\"line\":58,\"text\":\" rollback_restored = document.get(\\\"rollback_restored\\\")\"}\n{\"line\":59,\"text\":\" if not isinstance(changes, bool):\"}\n{\"line\":60,\"text\":\" raise ValueError(\\\"changes_made must be boolean\\\")\"}\n{\"line\":61,\"text\":\" if not isinstance(rollback_started, bool):\"}\n{\"line\":62,\"text\":\" raise ValueError(\\\"rollback_started must be boolean\\\")\"}\n{\"line\":63,\"text\":\" if rollback_restored is not None and not isinstance(\"}\n{\"line\":64,\"text\":\" rollback_restored,\"}\n{\"line\":65,\"text\":\" bool,\"}\n{\"line\":66,\"text\":\" ):\"}\n{\"line\":67,\"text\":\" raise ValueError(\"}\n{\"line\":68,\"text\":\" \\\"rollback_restored must be boolean or null\\\"\"}\n{\"line\":69,\"text\":\" )\"}\n{\"line\":70,\"text\":\" if rollback_restored is True and rollback_started is not True:\"}\n{\"line\":71,\"text\":\" raise ValueError(\"}\n{\"line\":72,\"text\":\" \\\"rollback_restored without rollback_started\\\"\"}\n{\"line\":73,\"text\":\" )\"}\n{\"line\":74,\"text\":\" if rollback_started is True and changes is not True:\"}\n{\"line\":75,\"text\":\" raise ValueError(\"}\n{\"line\":76,\"text\":\" \\\"rollback_started without changes\\\"\"}\n{\"line\":77,\"text\":\" )\"}\n{\"line\":78,\"text\":\" if status == \\\"BLOCKED\\\" and (\"}\n{\"line\":79,\"text\":\" changes\"}\n{\"line\":80,\"text\":\" or rollback_started\"}\n{\"line\":81,\"text\":\" or command_rc != 2\"}\n{\"line\":82,\"text\":\" ):\"}\n{\"line\":83,\"text\":\" raise ValueError(\"}\n{\"line\":84,\"text\":\" \\\"BLOCKED contract inconsistent with rc/mutation\\\"\"}\n{\"line\":85,\"text\":\" )\"}\n{\"line\":86,\"text\":\" if status == \\\"OK\\\" and command_rc != 0:\"}\n{\"line\":87,\"text\":\" raise ValueError(\\\"OK contract inconsistent with rc\\\")\"}\n{\"line\":88,\"text\":\" if status == \\\"FAIL\\\" and command_rc == 0:\"}\n{\"line\":89,\"text\":\" raise ValueError(\\\"FAIL contract inconsistent with rc\\\")\"}\n{\"line\":90,\"text\":\"\"}\n{\"line\":91,\"text\":\" if not changes:\"}\n{\"line\":92,\"text\":\" outcome = \\\"NO_MUTATION\\\"\"}\n{\"line\":93,\"text\":\" elif not rollback_started:\"}\n{\"line\":94,\"text\":\" outcome = \\\"MUTATED\\\"\"}\n{\"line\":95,\"text\":\" elif rollback_restored is True:\"}\n{\"line\":96,\"text\":\" outcome = \\\"ROLLED_BACK\\\"\"}\n{\"line\":97,\"text\":\" elif rollback_restored is False:\"}\n{\"line\":98,\"text\":\" outcome = \\\"ROLLBACK_FAILED\\\"\"}\n{\"line\":99,\"text\":\" else:\"}\n{\"line\":100,\"text\":\" outcome = \\\"ROLLBACK_UNKNOWN\\\"\"}\n{\"line\":101,\"text\":\"\"}\n{\"line\":102,\"text\":\" result = {\"}\n{\"line\":103,\"text\":\" \\\"valid\\\": True,\"}\n{\"line\":104,\"text\":\" \\\"status\\\": status,\"}\n{\"line\":105,\"text\":\" \\\"changes_made\\\": str(changes).lower(),\"}\n{\"line\":106,\"text\":\" \\\"rollback_started\\\": str(\"}\n{\"line\":107,\"text\":\" rollback_started\"}\n{\"line\":108,\"text\":\" ).lower(),\"}\n{\"line\":109,\"text\":\" \\\"rollback_restored\\\": (\"}\n{\"line\":110,\"text\":\" \\\"null\\\"\"}\n{\"line\":111,\"text\":\" if rollback_restored is None\"}\n{\"line\":112,\"text\":\" else str(rollback_restored).lower()\"}\n{\"line\":113,\"text\":\" ),\"}\n{\"line\":114,\"text\":\" \\\"mutation_outcome\\\": outcome,\"}\n{\"line\":115,\"text\":\" \\\"error\\\": \\\"NONE\\\",\"}\n{\"line\":116,\"text\":\" }\"}\n{\"line\":117,\"text\":\" except Exception as exc:\"}\n{\"line\":118,\"text\":\" result[\\\"error\\\"] = (\"}\n{\"line\":119,\"text\":\" \\\"INVALID_CONTRACT:\\\" + type(exc).__name__\"}\n{\"line\":122,\"text\":\" result[\\\"error\\\"] = \\\"MULTIPLE_CONTRACTS\\\"\"}\n{\"line\":123,\"text\":\"\"}\n{\"line\":124,\"text\":\"print(\\\"\\\\t\\\".join([\"}\n{\"line\":125,\"text\":\" str(result[\\\"valid\\\"]).lower(),\"}\n{\"line\":126,\"text\":\" result[\\\"status\\\"],\"}\n{\"line\":127,\"text\":\" result[\\\"changes_made\\\"],\"}\n{\"line\":128,\"text\":\" result[\\\"rollback_started\\\"],\"}\n{\"line\":129,\"text\":\" result[\\\"rollback_restored\\\"],\"}\n{\"line\":130,\"text\":\" result[\\\"mutation_outcome\\\"],\"}\n{\"line\":131,\"text\":\" result[\\\"error\\\"],\"}\n{\"line\":132,\"text\":\"]))\"}\n{\"line\":133,\"text\":\"PY_CONTRACT\"}\n{\"line\":134,\"text\":\"}\"}\n{\"line\":135,\"text\":\"\"}\n{\"line\":137,\"text\":\" local tmp\"}\n{\"line\":138,\"text\":\" tmp=\\\"$(mktemp)\\\"\"}\n{\"line\":139,\"text\":\" trap 'rm -f \\\"$tmp\\\"' RETURN\"}\n{\"line\":140,\"text\":\"\"}\n{\"line\":141,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":142,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T1\\\",\\\"status\\\":\\\"BLOCKED\\\",\\\"changes_made\\\":false,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":143,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":144,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T1 change 2)\\\" = \\\\\"}\n{\"line\":145,\"text\":\" $'true\\\\tBLOCKED\\\\tfalse\\\\tfalse\\\\tnull\\\\tNO_MUTATION\\\\tNONE' ]\"}\n{\"line\":146,\"text\":\"\"}\n{\"line\":147,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":148,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T2\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":149,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":150,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T2 change 0)\\\" = \\\\\"}\n{\"line\":151,\"text\":\" $'true\\\\tOK\\\\ttrue\\\\tfalse\\\\tnull\\\\tMUTATED\\\\tNONE' ]\"}\n{\"line\":152,\"text\":\"\"}\n{\"line\":153,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":154,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T3\\\",\\\"status\\\":\\\"FAIL\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":true,\\\"rollback_restored\\\":true}' \\\\\"}\n{\"line\":155,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":156,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T3 change 1)\\\" = \\\\\"}\n{\"line\":157,\"text\":\" $'true\\\\tFAIL\\\\ttrue\\\\ttrue\\\\ttrue\\\\tROLLED_BACK\\\\tNONE' ]\"}\n{\"line\":158,\"text\":\"\"}\n{\"line\":159,\"text\":\" : >\\\"$tmp\\\"\"}\n{\"line\":163,\"text\":\" printf '%s\\\\n' 'anything' >\\\"$tmp\\\"\"}\n{\"line\":164,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T5 verify 0)\\\" = \\\\\"}\n{\"line\":165,\"text\":\" $'true\\\\tNOT_APPLICABLE\\\\tfalse\\\\tfalse\\\\tnull\\\\tNO_MUTATION\\\\tNONE' ]\"}\n{\"line\":166,\"text\":\"\"}\n{\"line\":167,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":168,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"OTHER\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":169,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":170,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T6 change 0)\\\" = \\\\\"}\n{\"line\":171,\"text\":\" $'false\\\\tUNKNOWN\\\\tunknown\\\\tunknown\\\\tnull\\\\tUNKNOWN\\\\tINVALID_CONTRACT:ValueError' ]\"}\n{\"line\":172,\"text\":\"\"}\n{\"line\":173,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":174,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T7\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":175,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T7\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":176,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":177,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T7 change 0)\\\" = \\\\\"}\n{\"line\":178,\"text\":\" $'false\\\\tUNKNOWN\\\\tunknown\\\\tunknown\\\\tnull\\\\tUNKNOWN\\\\tMULTIPLE_CONTRACTS' ]\"}\n{\"line\":179,\"text\":\"\"}\n{\"line\":180,\"text\":\" echo 'SELF_TEST=PASS'\"}\n{\"line\":590,\"text\":\" sanitized_sha,\"}\n{\"line\":591,\"text\":\" run_started,\"}\n{\"line\":592,\"text\":\" repeat_blocked,\"}\n{\"line\":593,\"text\":\" block_reason,\"}\n{\"line\":594,\"text\":\" change_declared,\"}\n{\"line\":595,\"text\":\" result_contract_valid,\"}\n{\"line\":596,\"text\":\" contract_status,\"}\n{\"line\":597,\"text\":\" changes_made,\"}\n{\"line\":598,\"text\":\" rollback_started,\"}\n{\"line\":599,\"text\":\" rollback_restored,\"}\n{\"line\":600,\"text\":\" mutation_outcome,\"}\n{\"line\":601,\"text\":\" result_contract_error,\"}\n{\"line\":602,\"text\":\" command_rc,\"}\n{\"line\":603,\"text\":\") = sys.argv[1:]\"}\n{\"line\":604,\"text\":\"\"}\n{\"line\":605,\"text\":\"\"}\n{\"line\":606,\"text\":\"def optional_bool(value: str):\"}\n{\"line\":645,\"text\":\" \\\"command_sha256\\\": command_sha,\"}\n{\"line\":646,\"text\":\" \\\"duplicate_failed_command_blocked\\\": repeat_blocked == \\\"true\\\",\"}\n{\"line\":647,\"text\":\" \\\"block_reason\\\": block_reason or None,\"}\n{\"line\":648,\"text\":\" \\\"execution_started\\\": run_started == \\\"true\\\",\"}\n{\"line\":649,\"text\":\" \\\"change_declared\\\": change_declared == \\\"true\\\",\"}\n{\"line\":650,\"text\":\" \\\"result_contract_valid\\\": result_contract_valid == \\\"true\\\",\"}\n{\"line\":651,\"text\":\" \\\"result_contract_status\\\": (\"}\n{\"line\":652,\"text\":\" None\"}\n{\"line\":653,\"text\":\" if contract_status in {\\\"\\\", \\\"UNKNOWN\\\", \\\"NOT_APPLICABLE\\\"}\"}\n{\"line\":654,\"text\":\" else contract_status\"}\n{\"line\":655,\"text\":\" ),\"}\n{\"line\":656,\"text\":\" \\\"result_contract_error\\\": (\"}\n{\"line\":657,\"text\":\" None\"}\n{\"line\":658,\"text\":\" if result_contract_error == \\\"NONE\\\"\"}\n{\"line\":659,\"text\":\" else result_contract_error\"}\n{\"line\":660,\"text\":\" ),\"}\n{\"line\":661,\"text\":\" \\\"command_rc\\\": int(command_rc) if command_rc else None,\"}\n{\"line\":662,\"text\":\" \\\"changes_made\\\": optional_bool(changes_made),\"}\n{\"line\":663,\"text\":\" \\\"rollback_started\\\": optional_bool(rollback_started),\"}\n{\"line\":664,\"text\":\" \\\"rollback_restored\\\": optional_bool(rollback_restored),\"}\n{\"line\":665,\"text\":\" \\\"mutation_outcome\\\": mutation_outcome,\"}\n{\"line\":666,\"text\":\" \\\"sanitized\\\": True,\"}\n{\"line\":667,\"text\":\" \\\"secrets_included\\\": False,\"}\n{\"line\":668,\"text\":\" \\\"private_addresses_included\\\": False,\"}\n{\"line\":669,\"text\":\" \\\"raw_evidence_retained_locally\\\": True,\"}\n{\"line\":670,\"text\":\" \\\"raw_evidence_sha256\\\": raw_sha,\"}\nRUNNER_CONTRACT_VALIDATOR_SOURCE_END\nRUNNER_SELECTED_LINE_COUNT=203\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"NEWFI-260907-PORTAL200-APPLY3FAILRCA1\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\nNEWFI56_END\n" +} diff --git a/runtime/history/NEWFI-260907-PORTAL200-APPLY3FAILRCA1.txt b/runtime/history/NEWFI-260907-PORTAL200-APPLY3FAILRCA1.txt new file mode 100644 index 00000000..577f77ef --- /dev/null +++ b/runtime/history/NEWFI-260907-PORTAL200-APPLY3FAILRCA1.txt @@ -0,0 +1,250 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3FAILRCA1 +STATUS=OK +RC=0 +HOST=pve01 +MODE=read-only +COMPONENT=newfi-portal200-apply3-failure-contract-rca +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=01c670ca07e27a1cb55525fe1ea9c027122da3bc03abe444f5de750d8c345a62 +DUPLICATE_FAILED_COMMAND_BLOCKED=false +EXECUTION_STARTED=true +CHANGE_DECLARED=false +RESULT_CONTRACT_VALID=true +RESULT_CONTRACT_STATUS=NOT_APPLICABLE +RESULT_CONTRACT_ERROR=NONE +COMMAND_RC=0 +CHANGES_MADE=false +ROLLBACK_STARTED=false +ROLLBACK_RESTORED=null +MUTATION_OUTCOME=NO_MUTATION +SANITIZED=yes +SECRETS_INCLUDED=no +PRIVATE_ADDRESSES_INCLUDED=no +RAW_EVIDENCE_SHA256=b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12 +SANITIZED_OUTPUT_SHA256=b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12 +OUTPUT_BEGIN +NEWFI56_BEGIN +COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3FAILRCA1 +MUTATION_SCOPE=NONE_READ_ONLY +WRAPPER_BYTES=669 +WRAPPER_SHA256=dec036ea985e75d776b2de8c2bede77fe4b4aafa5da33648b2a6b5f79f3dec30 +APPLY3_SELECTED_OUTPUT_BEGIN +APPLY3_SELECTED_OUTPUT_END +APPLY3_SELECTED_LINE_COUNT=0 +RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d +RUNNER_BYTES=21321 +RUNNER_CONTRACT_VALIDATOR_SOURCE_BEGIN +{"line":12,"text":"command_rc = int(command_rc)"} +{"line":13,"text":""} +{"line":14,"text":"result = {"} +{"line":15,"text":" \"valid\": True,"} +{"line":16,"text":" \"status\": \"NOT_APPLICABLE\","} +{"line":17,"text":" \"changes_made\": \"false\","} +{"line":18,"text":" \"rollback_started\": \"false\","} +{"line":19,"text":" \"rollback_restored\": \"null\","} +{"line":20,"text":" \"mutation_outcome\": \"NO_MUTATION\","} +{"line":21,"text":" \"error\": \"NONE\","} +{"line":22,"text":"}"} +{"line":23,"text":""} +{"line":24,"text":"if mode == \"change\":"} +{"line":25,"text":" result = {"} +{"line":26,"text":" \"valid\": False,"} +{"line":27,"text":" \"status\": \"UNKNOWN\","} +{"line":28,"text":" \"changes_made\": \"unknown\","} +{"line":29,"text":" \"rollback_started\": \"unknown\","} +{"line":30,"text":" \"rollback_restored\": \"null\","} +{"line":31,"text":" \"mutation_outcome\": \"UNKNOWN\","} +{"line":32,"text":" \"error\": \"MISSING_CONTRACT\","} +{"line":33,"text":" }"} +{"line":34,"text":" marker = \"HOMELAB_RESULT_CONTRACT=\""} +{"line":35,"text":" lines = Path(raw_path).read_bytes().decode("} +{"line":36,"text":" \"utf-8\","} +{"line":37,"text":" errors=\"replace\","} +{"line":38,"text":" ).splitlines()"} +{"line":39,"text":" payloads = ["} +{"line":43,"text":" ]"} +{"line":44,"text":" if len(payloads) == 1:"} +{"line":45,"text":" try:"} +{"line":46,"text":" document = json.loads(payloads[0])"} +{"line":47,"text":" if not isinstance(document, dict):"} +{"line":48,"text":" raise ValueError(\"contract root is not object\")"} +{"line":49,"text":" if document.get(\"version\") != 1:"} +{"line":50,"text":" raise ValueError(\"unsupported version\")"} +{"line":51,"text":" if document.get(\"command_id\") != command_id:"} +{"line":52,"text":" raise ValueError(\"command_id mismatch\")"} +{"line":53,"text":" status = document.get(\"status\")"} +{"line":54,"text":" if status not in {\"OK\", \"BLOCKED\", \"FAIL\"}:"} +{"line":55,"text":" raise ValueError(\"invalid status\")"} +{"line":56,"text":" changes = document.get(\"changes_made\")"} +{"line":57,"text":" rollback_started = document.get(\"rollback_started\")"} +{"line":58,"text":" rollback_restored = document.get(\"rollback_restored\")"} +{"line":59,"text":" if not isinstance(changes, bool):"} +{"line":60,"text":" raise ValueError(\"changes_made must be boolean\")"} +{"line":61,"text":" if not isinstance(rollback_started, bool):"} +{"line":62,"text":" raise ValueError(\"rollback_started must be boolean\")"} +{"line":63,"text":" if rollback_restored is not None and not isinstance("} +{"line":64,"text":" rollback_restored,"} +{"line":65,"text":" bool,"} +{"line":66,"text":" ):"} +{"line":67,"text":" raise ValueError("} +{"line":68,"text":" \"rollback_restored must be boolean or null\""} +{"line":69,"text":" )"} +{"line":70,"text":" if rollback_restored is True and rollback_started is not True:"} +{"line":71,"text":" raise ValueError("} +{"line":72,"text":" \"rollback_restored without rollback_started\""} +{"line":73,"text":" )"} +{"line":74,"text":" if rollback_started is True and changes is not True:"} +{"line":75,"text":" raise ValueError("} +{"line":76,"text":" \"rollback_started without changes\""} +{"line":77,"text":" )"} +{"line":78,"text":" if status == \"BLOCKED\" and ("} +{"line":79,"text":" changes"} +{"line":80,"text":" or rollback_started"} +{"line":81,"text":" or command_rc != 2"} +{"line":82,"text":" ):"} +{"line":83,"text":" raise ValueError("} +{"line":84,"text":" \"BLOCKED contract inconsistent with rc/mutation\""} +{"line":85,"text":" )"} +{"line":86,"text":" if status == \"OK\" and command_rc != 0:"} +{"line":87,"text":" raise ValueError(\"OK contract inconsistent with rc\")"} +{"line":88,"text":" if status == \"FAIL\" and command_rc == 0:"} +{"line":89,"text":" raise ValueError(\"FAIL contract inconsistent with rc\")"} +{"line":90,"text":""} +{"line":91,"text":" if not changes:"} +{"line":92,"text":" outcome = \"NO_MUTATION\""} +{"line":93,"text":" elif not rollback_started:"} +{"line":94,"text":" outcome = \"MUTATED\""} +{"line":95,"text":" elif rollback_restored is True:"} +{"line":96,"text":" outcome = \"ROLLED_BACK\""} +{"line":97,"text":" elif rollback_restored is False:"} +{"line":98,"text":" outcome = \"ROLLBACK_FAILED\""} +{"line":99,"text":" else:"} +{"line":100,"text":" outcome = \"ROLLBACK_UNKNOWN\""} +{"line":101,"text":""} +{"line":102,"text":" result = {"} +{"line":103,"text":" \"valid\": True,"} +{"line":104,"text":" \"status\": status,"} +{"line":105,"text":" \"changes_made\": str(changes).lower(),"} +{"line":106,"text":" \"rollback_started\": str("} +{"line":107,"text":" rollback_started"} +{"line":108,"text":" ).lower(),"} +{"line":109,"text":" \"rollback_restored\": ("} +{"line":110,"text":" \"null\""} +{"line":111,"text":" if rollback_restored is None"} +{"line":112,"text":" else str(rollback_restored).lower()"} +{"line":113,"text":" ),"} +{"line":114,"text":" \"mutation_outcome\": outcome,"} +{"line":115,"text":" \"error\": \"NONE\","} +{"line":116,"text":" }"} +{"line":117,"text":" except Exception as exc:"} +{"line":118,"text":" result[\"error\"] = ("} +{"line":119,"text":" \"INVALID_CONTRACT:\" + type(exc).__name__"} +{"line":122,"text":" result[\"error\"] = \"MULTIPLE_CONTRACTS\""} +{"line":123,"text":""} +{"line":124,"text":"print(\"\\t\".join(["} +{"line":125,"text":" str(result[\"valid\"]).lower(),"} +{"line":126,"text":" result[\"status\"],"} +{"line":127,"text":" result[\"changes_made\"],"} +{"line":128,"text":" result[\"rollback_started\"],"} +{"line":129,"text":" result[\"rollback_restored\"],"} +{"line":130,"text":" result[\"mutation_outcome\"],"} +{"line":131,"text":" result[\"error\"],"} +{"line":132,"text":"]))"} +{"line":133,"text":"PY_CONTRACT"} +{"line":134,"text":"}"} +{"line":135,"text":""} +{"line":137,"text":" local tmp"} +{"line":138,"text":" tmp=\"$(mktemp)\""} +{"line":139,"text":" trap 'rm -f \"$tmp\"' RETURN"} +{"line":140,"text":""} +{"line":141,"text":" printf '%s\\n' \\"} +{"line":142,"text":" 'HOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"T1\",\"status\":\"BLOCKED\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}' \\"} +{"line":143,"text":" >\"$tmp\""} +{"line":144,"text":" [ \"$(read_mutation_contract \"$tmp\" T1 change 2)\" = \\"} +{"line":145,"text":" $'true\\tBLOCKED\\tfalse\\tfalse\\tnull\\tNO_MUTATION\\tNONE' ]"} +{"line":146,"text":""} +{"line":147,"text":" printf '%s\\n' \\"} +{"line":148,"text":" 'HOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"T2\",\"status\":\"OK\",\"changes_made\":true,\"rollback_started\":false,\"rollback_restored\":null}' \\"} +{"line":149,"text":" >\"$tmp\""} +{"line":150,"text":" [ \"$(read_mutation_contract \"$tmp\" T2 change 0)\" = \\"} +{"line":151,"text":" $'true\\tOK\\ttrue\\tfalse\\tnull\\tMUTATED\\tNONE' ]"} +{"line":152,"text":""} +{"line":153,"text":" printf '%s\\n' \\"} +{"line":154,"text":" 'HOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"T3\",\"status\":\"FAIL\",\"changes_made\":true,\"rollback_started\":true,\"rollback_restored\":true}' \\"} +{"line":155,"text":" >\"$tmp\""} +{"line":156,"text":" [ \"$(read_mutation_contract \"$tmp\" T3 change 1)\" = \\"} +{"line":157,"text":" $'true\\tFAIL\\ttrue\\ttrue\\ttrue\\tROLLED_BACK\\tNONE' ]"} +{"line":158,"text":""} +{"line":159,"text":" : >\"$tmp\""} +{"line":163,"text":" printf '%s\\n' 'anything' >\"$tmp\""} +{"line":164,"text":" [ \"$(read_mutation_contract \"$tmp\" T5 verify 0)\" = \\"} +{"line":165,"text":" $'true\\tNOT_APPLICABLE\\tfalse\\tfalse\\tnull\\tNO_MUTATION\\tNONE' ]"} +{"line":166,"text":""} +{"line":167,"text":" printf '%s\\n' \\"} +{"line":168,"text":" 'HOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"OTHER\",\"status\":\"OK\",\"changes_made\":true,\"rollback_started\":false,\"rollback_restored\":null}' \\"} +{"line":169,"text":" >\"$tmp\""} +{"line":170,"text":" [ \"$(read_mutation_contract \"$tmp\" T6 change 0)\" = \\"} +{"line":171,"text":" $'false\\tUNKNOWN\\tunknown\\tunknown\\tnull\\tUNKNOWN\\tINVALID_CONTRACT:ValueError' ]"} +{"line":172,"text":""} +{"line":173,"text":" printf '%s\\n' \\"} +{"line":174,"text":" 'HOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"T7\",\"status\":\"OK\",\"changes_made\":true,\"rollback_started\":false,\"rollback_restored\":null}' \\"} +{"line":175,"text":" 'HOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"T7\",\"status\":\"OK\",\"changes_made\":true,\"rollback_started\":false,\"rollback_restored\":null}' \\"} +{"line":176,"text":" >\"$tmp\""} +{"line":177,"text":" [ \"$(read_mutation_contract \"$tmp\" T7 change 0)\" = \\"} +{"line":178,"text":" $'false\\tUNKNOWN\\tunknown\\tunknown\\tnull\\tUNKNOWN\\tMULTIPLE_CONTRACTS' ]"} +{"line":179,"text":""} +{"line":180,"text":" echo 'SELF_TEST=PASS'"} +{"line":590,"text":" sanitized_sha,"} +{"line":591,"text":" run_started,"} +{"line":592,"text":" repeat_blocked,"} +{"line":593,"text":" block_reason,"} +{"line":594,"text":" change_declared,"} +{"line":595,"text":" result_contract_valid,"} +{"line":596,"text":" contract_status,"} +{"line":597,"text":" changes_made,"} +{"line":598,"text":" rollback_started,"} +{"line":599,"text":" rollback_restored,"} +{"line":600,"text":" mutation_outcome,"} +{"line":601,"text":" result_contract_error,"} +{"line":602,"text":" command_rc,"} +{"line":603,"text":") = sys.argv[1:]"} +{"line":604,"text":""} +{"line":605,"text":""} +{"line":606,"text":"def optional_bool(value: str):"} +{"line":645,"text":" \"command_sha256\": command_sha,"} +{"line":646,"text":" \"duplicate_failed_command_blocked\": repeat_blocked == \"true\","} +{"line":647,"text":" \"block_reason\": block_reason or None,"} +{"line":648,"text":" \"execution_started\": run_started == \"true\","} +{"line":649,"text":" \"change_declared\": change_declared == \"true\","} +{"line":650,"text":" \"result_contract_valid\": result_contract_valid == \"true\","} +{"line":651,"text":" \"result_contract_status\": ("} +{"line":652,"text":" None"} +{"line":653,"text":" if contract_status in {\"\", \"UNKNOWN\", \"NOT_APPLICABLE\"}"} +{"line":654,"text":" else contract_status"} +{"line":655,"text":" ),"} +{"line":656,"text":" \"result_contract_error\": ("} +{"line":657,"text":" None"} +{"line":658,"text":" if result_contract_error == \"NONE\""} +{"line":659,"text":" else result_contract_error"} +{"line":660,"text":" ),"} +{"line":661,"text":" \"command_rc\": int(command_rc) if command_rc else None,"} +{"line":662,"text":" \"changes_made\": optional_bool(changes_made),"} +{"line":663,"text":" \"rollback_started\": optional_bool(rollback_started),"} +{"line":664,"text":" \"rollback_restored\": optional_bool(rollback_restored),"} +{"line":665,"text":" \"mutation_outcome\": mutation_outcome,"} +{"line":666,"text":" \"sanitized\": True,"} +{"line":667,"text":" \"secrets_included\": False,"} +{"line":668,"text":" \"private_addresses_included\": False,"} +{"line":669,"text":" \"raw_evidence_retained_locally\": True,"} +{"line":670,"text":" \"raw_evidence_sha256\": raw_sha,"} +RUNNER_CONTRACT_VALIDATOR_SOURCE_END +RUNNER_SELECTED_LINE_COUNT=203 +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"NEWFI-260907-PORTAL200-APPLY3FAILRCA1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} +NEWFI56_END + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index f082683b..539a1893 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "NEWFI-260907-PORTAL200-APPLY3RCA1", + "command_id": "NEWFI-260907-PORTAL200-APPLY3FAILRCA1", "status": "OK", "rc": 0, "host": "pve01", "mode": "read-only", - "component": "newfi-portal200-apply3-rca", - "started_at_utc": "2026-09-07T11:24:50Z", - "finished_at_utc": "2026-09-07T11:24:52Z", + "component": "newfi-portal200-apply3-failure-contract-rca", + "started_at_utc": "2026-09-07T11:31:38Z", + "finished_at_utc": "2026-09-07T11:31:38Z", "reference_register_checked": true, "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", "error_register_checked": true, "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "ed9e63a542099ec6e649d45aba789c8193600c8fb6ba0cb52d92e160c1ba5d45", + "command_sha256": "01c670ca07e27a1cb55525fe1ea9c027122da3bc03abe444f5de750d8c345a62", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "ddd2941f326ba6cecf9755d25f37bcfd721945dbc4f845a57d0ae557d3a70855", - "sanitized_output_sha256": "ddd2941f326ba6cecf9755d25f37bcfd721945dbc4f845a57d0ae557d3a70855", + "raw_evidence_sha256": "b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12", + "sanitized_output_sha256": "b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "NEWFI55_BEGIN\nCOMMAND_ID=NEWFI-260907-PORTAL200-APPLY3RCA1\nRCA_TARGET_FAILED_COMMAND=NEWFI-260907-PORTAL200-APPLY3\nPORTAL200_ROADMAP_REMAINS=22\nRCA_MUTATION_SCOPE=NONE_READ_ONLY\nRCA_WRAPPER_BYTES=669\nRCA_WRAPPER_SHA256=dec036ea985e75d776b2de8c2bede77fe4b4aafa5da33648b2a6b5f79f3dec30\nRCA_WRAPPER_SELECTED_LINE_COUNT=4\nRCA_WRAPPER_SELECTED_BEGIN\nCOMMAND_ID=NEWFI-260907-PORTAL200-APPLY3\nCOMMAND_ID=NEWFI-260907-PORTAL200-APPLY3\nSTATUS=FAIL\nRC=76\nRCA_WRAPPER_SELECTED_END\nRCA_GIT_STATE={\"branch\":\"implementation/newfi-closed-mvp-20260906\",\"clean\":true,\"head\":\"06bab5acd124e768f70305b3d7eca2f595871890\",\"remote\":\"06bab5acd124e768f70305b3d7eca2f595871890\",\"status_lines\":[]}\nRCA_STAGING_STATE={\"application\":{\"boardActive\":\"0\",\"boardUrl\":\"http://newfi-staging.gram1.ru\",\"error_count\":8,\"error_max_id\":40,\"indexRoute\":\"portal/\"},\"hostname\":\"newfi-staging\",\"new_errors\":[],\"source\":{\"controller\":{\"bytes\":247,\"sha256\":\"53909e753ea5a011550fd280ad1c342a74ca9949be092dfbd95244243cae92f3\"},\"service\":null,\"templates_xml\":{\"bytes\":1461,\"sha256\":\"c29c04f8b937284e821c87957653e87c2f6ac014fac30648a0f6b18e84392adf\"}},\"templates\":[{\"bytes\":1274,\"css_marker\":0,\"html_marker\":0,\"sha256\":\"1f484c8cf6bdeda8fda2974abf8a57f8cc7453fe2a779af7c735afa3b73aa741\",\"style_id\":0,\"title\":\"newfi_portal\"}]}\nRCA_PROD_STATE={\"application\":{\"boardActive\":\"1\",\"boardUrl\":\"https://newfi.ru\",\"error_count\":0,\"error_max_id\":0,\"indexRoute\":\"portal/\"},\"hostname\":\"newfi-prod\",\"new_errors\":[],\"source\":{\"controller\":{\"bytes\":247,\"sha256\":\"53909e753ea5a011550fd280ad1c342a74ca9949be092dfbd95244243cae92f3\"},\"service\":null,\"templates_xml\":{\"bytes\":1461,\"sha256\":\"c29c04f8b937284e821c87957653e87c2f6ac014fac30648a0f6b18e84392adf\"}},\"templates\":[{\"bytes\":1274,\"css_marker\":0,\"html_marker\":0,\"sha256\":\"1f484c8cf6bdeda8fda2974abf8a57f8cc7453fe2a779af7c735afa3b73aa741\",\"style_id\":0,\"title\":\"newfi_portal\"}]}\nRCA_STATE_SUMMARY={\"clean_old_prestate\":true,\"git_clean\":true,\"git_old_head\":true,\"prod_error_max\":0,\"prod_source\":\"OLD\",\"prod_templates\":\"OLD\",\"staging_error_max\":40,\"staging_source\":\"OLD\",\"staging_templates\":\"OLD\"}\nRCA_RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nRCA_RUNNER_BYTES=21321\nRCA_RUNNER_CONTRACT_SOURCE_BEGIN\n{\"line\":14,\"text\":\"result = {\"}\n{\"line\":15,\"text\":\" \\\"valid\\\": True,\"}\n{\"line\":16,\"text\":\" \\\"status\\\": \\\"NOT_APPLICABLE\\\",\"}\n{\"line\":17,\"text\":\" \\\"changes_made\\\": \\\"false\\\",\"}\n{\"line\":18,\"text\":\" \\\"rollback_started\\\": \\\"false\\\",\"}\n{\"line\":19,\"text\":\" \\\"rollback_restored\\\": \\\"null\\\",\"}\n{\"line\":20,\"text\":\" \\\"mutation_outcome\\\": \\\"NO_MUTATION\\\",\"}\n{\"line\":21,\"text\":\" \\\"error\\\": \\\"NONE\\\",\"}\n{\"line\":22,\"text\":\"}\"}\n{\"line\":25,\"text\":\" result = {\"}\n{\"line\":26,\"text\":\" \\\"valid\\\": False,\"}\n{\"line\":27,\"text\":\" \\\"status\\\": \\\"UNKNOWN\\\",\"}\n{\"line\":28,\"text\":\" \\\"changes_made\\\": \\\"unknown\\\",\"}\n{\"line\":29,\"text\":\" \\\"rollback_started\\\": \\\"unknown\\\",\"}\n{\"line\":30,\"text\":\" \\\"rollback_restored\\\": \\\"null\\\",\"}\n{\"line\":31,\"text\":\" \\\"mutation_outcome\\\": \\\"UNKNOWN\\\",\"}\n{\"line\":32,\"text\":\" \\\"error\\\": \\\"MISSING_CONTRACT\\\",\"}\n{\"line\":33,\"text\":\" }\"}\n{\"line\":34,\"text\":\" marker = \\\"HOMELAB_RESULT_CONTRACT=\\\"\"}\n{\"line\":35,\"text\":\" lines = Path(raw_path).read_bytes().decode(\"}\n{\"line\":36,\"text\":\" \\\"utf-8\\\",\"}\n{\"line\":37,\"text\":\" errors=\\\"replace\\\",\"}\n{\"line\":45,\"text\":\" try:\"}\n{\"line\":46,\"text\":\" document = json.loads(payloads[0])\"}\n{\"line\":47,\"text\":\" if not isinstance(document, dict):\"}\n{\"line\":48,\"text\":\" raise ValueError(\\\"contract root is not object\\\")\"}\n{\"line\":49,\"text\":\" if document.get(\\\"version\\\") != 1:\"}\n{\"line\":50,\"text\":\" raise ValueError(\\\"unsupported version\\\")\"}\n{\"line\":51,\"text\":\" if document.get(\\\"command_id\\\") != command_id:\"}\n{\"line\":52,\"text\":\" raise ValueError(\\\"command_id mismatch\\\")\"}\n{\"line\":53,\"text\":\" status = document.get(\\\"status\\\")\"}\n{\"line\":54,\"text\":\" if status not in {\\\"OK\\\", \\\"BLOCKED\\\", \\\"FAIL\\\"}:\"}\n{\"line\":55,\"text\":\" raise ValueError(\\\"invalid status\\\")\"}\n{\"line\":56,\"text\":\" changes = document.get(\\\"changes_made\\\")\"}\n{\"line\":57,\"text\":\" rollback_started = document.get(\\\"rollback_started\\\")\"}\n{\"line\":58,\"text\":\" rollback_restored = document.get(\\\"rollback_restored\\\")\"}\n{\"line\":59,\"text\":\" if not isinstance(changes, bool):\"}\n{\"line\":60,\"text\":\" raise ValueError(\\\"changes_made must be boolean\\\")\"}\n{\"line\":61,\"text\":\" if not isinstance(rollback_started, bool):\"}\n{\"line\":62,\"text\":\" raise ValueError(\\\"rollback_started must be boolean\\\")\"}\n{\"line\":63,\"text\":\" if rollback_restored is not None and not isinstance(\"}\n{\"line\":64,\"text\":\" rollback_restored,\"}\n{\"line\":65,\"text\":\" bool,\"}\n{\"line\":66,\"text\":\" ):\"}\n{\"line\":67,\"text\":\" raise ValueError(\"}\n{\"line\":68,\"text\":\" \\\"rollback_restored must be boolean or null\\\"\"}\n{\"line\":69,\"text\":\" )\"}\n{\"line\":70,\"text\":\" if rollback_restored is True and rollback_started is not True:\"}\n{\"line\":71,\"text\":\" raise ValueError(\"}\n{\"line\":72,\"text\":\" \\\"rollback_restored without rollback_started\\\"\"}\n{\"line\":73,\"text\":\" )\"}\n{\"line\":74,\"text\":\" if rollback_started is True and changes is not True:\"}\n{\"line\":75,\"text\":\" raise ValueError(\"}\n{\"line\":76,\"text\":\" \\\"rollback_started without changes\\\"\"}\n{\"line\":77,\"text\":\" )\"}\n{\"line\":78,\"text\":\" if status == \\\"BLOCKED\\\" and (\"}\n{\"line\":79,\"text\":\" changes\"}\n{\"line\":80,\"text\":\" or rollback_started\"}\n{\"line\":81,\"text\":\" or command_rc != 2\"}\n{\"line\":82,\"text\":\" ):\"}\n{\"line\":83,\"text\":\" raise ValueError(\"}\n{\"line\":84,\"text\":\" \\\"BLOCKED contract inconsistent with rc/mutation\\\"\"}\n{\"line\":85,\"text\":\" )\"}\n{\"line\":86,\"text\":\" if status == \\\"OK\\\" and command_rc != 0:\"}\n{\"line\":87,\"text\":\" raise ValueError(\\\"OK contract inconsistent with rc\\\")\"}\n{\"line\":88,\"text\":\" if status == \\\"FAIL\\\" and command_rc == 0:\"}\n{\"line\":89,\"text\":\" raise ValueError(\\\"FAIL contract inconsistent with rc\\\")\"}\n{\"line\":90,\"text\":\"\"}\n{\"line\":91,\"text\":\" if not changes:\"}\n{\"line\":92,\"text\":\" outcome = \\\"NO_MUTATION\\\"\"}\n{\"line\":93,\"text\":\" elif not rollback_started:\"}\n{\"line\":94,\"text\":\" outcome = \\\"MUTATED\\\"\"}\n{\"line\":95,\"text\":\" elif rollback_restored is True:\"}\n{\"line\":96,\"text\":\" outcome = \\\"ROLLED_BACK\\\"\"}\n{\"line\":97,\"text\":\" elif rollback_restored is False:\"}\n{\"line\":98,\"text\":\" outcome = \\\"ROLLBACK_FAILED\\\"\"}\n{\"line\":99,\"text\":\" else:\"}\n{\"line\":100,\"text\":\" outcome = \\\"ROLLBACK_UNKNOWN\\\"\"}\n{\"line\":102,\"text\":\" result = {\"}\n{\"line\":103,\"text\":\" \\\"valid\\\": True,\"}\n{\"line\":104,\"text\":\" \\\"status\\\": status,\"}\n{\"line\":105,\"text\":\" \\\"changes_made\\\": str(changes).lower(),\"}\n{\"line\":106,\"text\":\" \\\"rollback_started\\\": str(\"}\n{\"line\":107,\"text\":\" rollback_started\"}\n{\"line\":108,\"text\":\" ).lower(),\"}\n{\"line\":109,\"text\":\" \\\"rollback_restored\\\": (\"}\n{\"line\":110,\"text\":\" \\\"null\\\"\"}\n{\"line\":111,\"text\":\" if rollback_restored is None\"}\n{\"line\":112,\"text\":\" else str(rollback_restored).lower()\"}\n{\"line\":113,\"text\":\" ),\"}\n{\"line\":114,\"text\":\" \\\"mutation_outcome\\\": outcome,\"}\n{\"line\":115,\"text\":\" \\\"error\\\": \\\"NONE\\\",\"}\n{\"line\":124,\"text\":\"print(\\\"\\\\t\\\".join([\"}\n{\"line\":125,\"text\":\" str(result[\\\"valid\\\"]).lower(),\"}\n{\"line\":126,\"text\":\" result[\\\"status\\\"],\"}\n{\"line\":127,\"text\":\" result[\\\"changes_made\\\"],\"}\n{\"line\":128,\"text\":\" result[\\\"rollback_started\\\"],\"}\n{\"line\":129,\"text\":\" result[\\\"rollback_restored\\\"],\"}\n{\"line\":130,\"text\":\" result[\\\"mutation_outcome\\\"],\"}\n{\"line\":131,\"text\":\" result[\\\"error\\\"],\"}\n{\"line\":132,\"text\":\"]))\"}\n{\"line\":139,\"text\":\" trap 'rm -f \\\"$tmp\\\"' RETURN\"}\n{\"line\":140,\"text\":\"\"}\n{\"line\":141,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":142,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T1\\\",\\\"status\\\":\\\"BLOCKED\\\",\\\"changes_made\\\":false,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":143,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":144,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T1 change 2)\\\" = \\\\\"}\n{\"line\":145,\"text\":\" $'true\\\\tBLOCKED\\\\tfalse\\\\tfalse\\\\tnull\\\\tNO_MUTATION\\\\tNONE' ]\"}\n{\"line\":146,\"text\":\"\"}\n{\"line\":147,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":148,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T2\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":149,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":150,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T2 change 0)\\\" = \\\\\"}\n{\"line\":151,\"text\":\" $'true\\\\tOK\\\\ttrue\\\\tfalse\\\\tnull\\\\tMUTATED\\\\tNONE' ]\"}\n{\"line\":152,\"text\":\"\"}\n{\"line\":153,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":154,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T3\\\",\\\"status\\\":\\\"FAIL\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":true,\\\"rollback_restored\\\":true}' \\\\\"}\n{\"line\":155,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":156,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T3 change 1)\\\" = \\\\\"}\n{\"line\":157,\"text\":\" $'true\\\\tFAIL\\\\ttrue\\\\ttrue\\\\ttrue\\\\tROLLED_BACK\\\\tNONE' ]\"}\n{\"line\":165,\"text\":\" $'true\\\\tNOT_APPLICABLE\\\\tfalse\\\\tfalse\\\\tnull\\\\tNO_MUTATION\\\\tNONE' ]\"}\n{\"line\":166,\"text\":\"\"}\n{\"line\":167,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":168,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"OTHER\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":169,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":170,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T6 change 0)\\\" = \\\\\"}\n{\"line\":171,\"text\":\" $'false\\\\tUNKNOWN\\\\tunknown\\\\tunknown\\\\tnull\\\\tUNKNOWN\\\\tINVALID_CONTRACT:ValueError' ]\"}\n{\"line\":172,\"text\":\"\"}\n{\"line\":173,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":174,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T7\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":175,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T7\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":176,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":177,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T7 change 0)\\\" = \\\\\"}\n{\"line\":178,\"text\":\" $'false\\\\tUNKNOWN\\\\tunknown\\\\tunknown\\\\tnull\\\\tUNKNOWN\\\\tMULTIPLE_CONTRACTS' ]\"}\n{\"line\":594,\"text\":\" change_declared,\"}\n{\"line\":595,\"text\":\" result_contract_valid,\"}\n{\"line\":596,\"text\":\" contract_status,\"}\n{\"line\":597,\"text\":\" changes_made,\"}\n{\"line\":598,\"text\":\" rollback_started,\"}\n{\"line\":599,\"text\":\" rollback_restored,\"}\n{\"line\":600,\"text\":\" mutation_outcome,\"}\n{\"line\":601,\"text\":\" result_contract_error,\"}\n{\"line\":602,\"text\":\" command_rc,\"}\n{\"line\":659,\"text\":\" else result_contract_error\"}\n{\"line\":660,\"text\":\" ),\"}\n{\"line\":661,\"text\":\" \\\"command_rc\\\": int(command_rc) if command_rc else None,\"}\n{\"line\":662,\"text\":\" \\\"changes_made\\\": optional_bool(changes_made),\"}\n{\"line\":663,\"text\":\" \\\"rollback_started\\\": optional_bool(rollback_started),\"}\n{\"line\":664,\"text\":\" \\\"rollback_restored\\\": optional_bool(rollback_restored),\"}\n{\"line\":665,\"text\":\" \\\"mutation_outcome\\\": mutation_outcome,\"}\n{\"line\":666,\"text\":\" \\\"sanitized\\\": True,\"}\n{\"line\":667,\"text\":\" \\\"secrets_included\\\": False,\"}\nRCA_RUNNER_CONTRACT_SOURCE_END\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"NEWFI-260907-PORTAL200-APPLY3RCA1\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\nNEWFI55_END\n" + "output": "NEWFI56_BEGIN\nCOMMAND_ID=NEWFI-260907-PORTAL200-APPLY3FAILRCA1\nMUTATION_SCOPE=NONE_READ_ONLY\nWRAPPER_BYTES=669\nWRAPPER_SHA256=dec036ea985e75d776b2de8c2bede77fe4b4aafa5da33648b2a6b5f79f3dec30\nAPPLY3_SELECTED_OUTPUT_BEGIN\nAPPLY3_SELECTED_OUTPUT_END\nAPPLY3_SELECTED_LINE_COUNT=0\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nRUNNER_BYTES=21321\nRUNNER_CONTRACT_VALIDATOR_SOURCE_BEGIN\n{\"line\":12,\"text\":\"command_rc = int(command_rc)\"}\n{\"line\":13,\"text\":\"\"}\n{\"line\":14,\"text\":\"result = {\"}\n{\"line\":15,\"text\":\" \\\"valid\\\": True,\"}\n{\"line\":16,\"text\":\" \\\"status\\\": \\\"NOT_APPLICABLE\\\",\"}\n{\"line\":17,\"text\":\" \\\"changes_made\\\": \\\"false\\\",\"}\n{\"line\":18,\"text\":\" \\\"rollback_started\\\": \\\"false\\\",\"}\n{\"line\":19,\"text\":\" \\\"rollback_restored\\\": \\\"null\\\",\"}\n{\"line\":20,\"text\":\" \\\"mutation_outcome\\\": \\\"NO_MUTATION\\\",\"}\n{\"line\":21,\"text\":\" \\\"error\\\": \\\"NONE\\\",\"}\n{\"line\":22,\"text\":\"}\"}\n{\"line\":23,\"text\":\"\"}\n{\"line\":24,\"text\":\"if mode == \\\"change\\\":\"}\n{\"line\":25,\"text\":\" result = {\"}\n{\"line\":26,\"text\":\" \\\"valid\\\": False,\"}\n{\"line\":27,\"text\":\" \\\"status\\\": \\\"UNKNOWN\\\",\"}\n{\"line\":28,\"text\":\" \\\"changes_made\\\": \\\"unknown\\\",\"}\n{\"line\":29,\"text\":\" \\\"rollback_started\\\": \\\"unknown\\\",\"}\n{\"line\":30,\"text\":\" \\\"rollback_restored\\\": \\\"null\\\",\"}\n{\"line\":31,\"text\":\" \\\"mutation_outcome\\\": \\\"UNKNOWN\\\",\"}\n{\"line\":32,\"text\":\" \\\"error\\\": \\\"MISSING_CONTRACT\\\",\"}\n{\"line\":33,\"text\":\" }\"}\n{\"line\":34,\"text\":\" marker = \\\"HOMELAB_RESULT_CONTRACT=\\\"\"}\n{\"line\":35,\"text\":\" lines = Path(raw_path).read_bytes().decode(\"}\n{\"line\":36,\"text\":\" \\\"utf-8\\\",\"}\n{\"line\":37,\"text\":\" errors=\\\"replace\\\",\"}\n{\"line\":38,\"text\":\" ).splitlines()\"}\n{\"line\":39,\"text\":\" payloads = [\"}\n{\"line\":43,\"text\":\" ]\"}\n{\"line\":44,\"text\":\" if len(payloads) == 1:\"}\n{\"line\":45,\"text\":\" try:\"}\n{\"line\":46,\"text\":\" document = json.loads(payloads[0])\"}\n{\"line\":47,\"text\":\" if not isinstance(document, dict):\"}\n{\"line\":48,\"text\":\" raise ValueError(\\\"contract root is not object\\\")\"}\n{\"line\":49,\"text\":\" if document.get(\\\"version\\\") != 1:\"}\n{\"line\":50,\"text\":\" raise ValueError(\\\"unsupported version\\\")\"}\n{\"line\":51,\"text\":\" if document.get(\\\"command_id\\\") != command_id:\"}\n{\"line\":52,\"text\":\" raise ValueError(\\\"command_id mismatch\\\")\"}\n{\"line\":53,\"text\":\" status = document.get(\\\"status\\\")\"}\n{\"line\":54,\"text\":\" if status not in {\\\"OK\\\", \\\"BLOCKED\\\", \\\"FAIL\\\"}:\"}\n{\"line\":55,\"text\":\" raise ValueError(\\\"invalid status\\\")\"}\n{\"line\":56,\"text\":\" changes = document.get(\\\"changes_made\\\")\"}\n{\"line\":57,\"text\":\" rollback_started = document.get(\\\"rollback_started\\\")\"}\n{\"line\":58,\"text\":\" rollback_restored = document.get(\\\"rollback_restored\\\")\"}\n{\"line\":59,\"text\":\" if not isinstance(changes, bool):\"}\n{\"line\":60,\"text\":\" raise ValueError(\\\"changes_made must be boolean\\\")\"}\n{\"line\":61,\"text\":\" if not isinstance(rollback_started, bool):\"}\n{\"line\":62,\"text\":\" raise ValueError(\\\"rollback_started must be boolean\\\")\"}\n{\"line\":63,\"text\":\" if rollback_restored is not None and not isinstance(\"}\n{\"line\":64,\"text\":\" rollback_restored,\"}\n{\"line\":65,\"text\":\" bool,\"}\n{\"line\":66,\"text\":\" ):\"}\n{\"line\":67,\"text\":\" raise ValueError(\"}\n{\"line\":68,\"text\":\" \\\"rollback_restored must be boolean or null\\\"\"}\n{\"line\":69,\"text\":\" )\"}\n{\"line\":70,\"text\":\" if rollback_restored is True and rollback_started is not True:\"}\n{\"line\":71,\"text\":\" raise ValueError(\"}\n{\"line\":72,\"text\":\" \\\"rollback_restored without rollback_started\\\"\"}\n{\"line\":73,\"text\":\" )\"}\n{\"line\":74,\"text\":\" if rollback_started is True and changes is not True:\"}\n{\"line\":75,\"text\":\" raise ValueError(\"}\n{\"line\":76,\"text\":\" \\\"rollback_started without changes\\\"\"}\n{\"line\":77,\"text\":\" )\"}\n{\"line\":78,\"text\":\" if status == \\\"BLOCKED\\\" and (\"}\n{\"line\":79,\"text\":\" changes\"}\n{\"line\":80,\"text\":\" or rollback_started\"}\n{\"line\":81,\"text\":\" or command_rc != 2\"}\n{\"line\":82,\"text\":\" ):\"}\n{\"line\":83,\"text\":\" raise ValueError(\"}\n{\"line\":84,\"text\":\" \\\"BLOCKED contract inconsistent with rc/mutation\\\"\"}\n{\"line\":85,\"text\":\" )\"}\n{\"line\":86,\"text\":\" if status == \\\"OK\\\" and command_rc != 0:\"}\n{\"line\":87,\"text\":\" raise ValueError(\\\"OK contract inconsistent with rc\\\")\"}\n{\"line\":88,\"text\":\" if status == \\\"FAIL\\\" and command_rc == 0:\"}\n{\"line\":89,\"text\":\" raise ValueError(\\\"FAIL contract inconsistent with rc\\\")\"}\n{\"line\":90,\"text\":\"\"}\n{\"line\":91,\"text\":\" if not changes:\"}\n{\"line\":92,\"text\":\" outcome = \\\"NO_MUTATION\\\"\"}\n{\"line\":93,\"text\":\" elif not rollback_started:\"}\n{\"line\":94,\"text\":\" outcome = \\\"MUTATED\\\"\"}\n{\"line\":95,\"text\":\" elif rollback_restored is True:\"}\n{\"line\":96,\"text\":\" outcome = \\\"ROLLED_BACK\\\"\"}\n{\"line\":97,\"text\":\" elif rollback_restored is False:\"}\n{\"line\":98,\"text\":\" outcome = \\\"ROLLBACK_FAILED\\\"\"}\n{\"line\":99,\"text\":\" else:\"}\n{\"line\":100,\"text\":\" outcome = \\\"ROLLBACK_UNKNOWN\\\"\"}\n{\"line\":101,\"text\":\"\"}\n{\"line\":102,\"text\":\" result = {\"}\n{\"line\":103,\"text\":\" \\\"valid\\\": True,\"}\n{\"line\":104,\"text\":\" \\\"status\\\": status,\"}\n{\"line\":105,\"text\":\" \\\"changes_made\\\": str(changes).lower(),\"}\n{\"line\":106,\"text\":\" \\\"rollback_started\\\": str(\"}\n{\"line\":107,\"text\":\" rollback_started\"}\n{\"line\":108,\"text\":\" ).lower(),\"}\n{\"line\":109,\"text\":\" \\\"rollback_restored\\\": (\"}\n{\"line\":110,\"text\":\" \\\"null\\\"\"}\n{\"line\":111,\"text\":\" if rollback_restored is None\"}\n{\"line\":112,\"text\":\" else str(rollback_restored).lower()\"}\n{\"line\":113,\"text\":\" ),\"}\n{\"line\":114,\"text\":\" \\\"mutation_outcome\\\": outcome,\"}\n{\"line\":115,\"text\":\" \\\"error\\\": \\\"NONE\\\",\"}\n{\"line\":116,\"text\":\" }\"}\n{\"line\":117,\"text\":\" except Exception as exc:\"}\n{\"line\":118,\"text\":\" result[\\\"error\\\"] = (\"}\n{\"line\":119,\"text\":\" \\\"INVALID_CONTRACT:\\\" + type(exc).__name__\"}\n{\"line\":122,\"text\":\" result[\\\"error\\\"] = \\\"MULTIPLE_CONTRACTS\\\"\"}\n{\"line\":123,\"text\":\"\"}\n{\"line\":124,\"text\":\"print(\\\"\\\\t\\\".join([\"}\n{\"line\":125,\"text\":\" str(result[\\\"valid\\\"]).lower(),\"}\n{\"line\":126,\"text\":\" result[\\\"status\\\"],\"}\n{\"line\":127,\"text\":\" result[\\\"changes_made\\\"],\"}\n{\"line\":128,\"text\":\" result[\\\"rollback_started\\\"],\"}\n{\"line\":129,\"text\":\" result[\\\"rollback_restored\\\"],\"}\n{\"line\":130,\"text\":\" result[\\\"mutation_outcome\\\"],\"}\n{\"line\":131,\"text\":\" result[\\\"error\\\"],\"}\n{\"line\":132,\"text\":\"]))\"}\n{\"line\":133,\"text\":\"PY_CONTRACT\"}\n{\"line\":134,\"text\":\"}\"}\n{\"line\":135,\"text\":\"\"}\n{\"line\":137,\"text\":\" local tmp\"}\n{\"line\":138,\"text\":\" tmp=\\\"$(mktemp)\\\"\"}\n{\"line\":139,\"text\":\" trap 'rm -f \\\"$tmp\\\"' RETURN\"}\n{\"line\":140,\"text\":\"\"}\n{\"line\":141,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":142,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T1\\\",\\\"status\\\":\\\"BLOCKED\\\",\\\"changes_made\\\":false,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":143,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":144,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T1 change 2)\\\" = \\\\\"}\n{\"line\":145,\"text\":\" $'true\\\\tBLOCKED\\\\tfalse\\\\tfalse\\\\tnull\\\\tNO_MUTATION\\\\tNONE' ]\"}\n{\"line\":146,\"text\":\"\"}\n{\"line\":147,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":148,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T2\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":149,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":150,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T2 change 0)\\\" = \\\\\"}\n{\"line\":151,\"text\":\" $'true\\\\tOK\\\\ttrue\\\\tfalse\\\\tnull\\\\tMUTATED\\\\tNONE' ]\"}\n{\"line\":152,\"text\":\"\"}\n{\"line\":153,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":154,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T3\\\",\\\"status\\\":\\\"FAIL\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":true,\\\"rollback_restored\\\":true}' \\\\\"}\n{\"line\":155,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":156,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T3 change 1)\\\" = \\\\\"}\n{\"line\":157,\"text\":\" $'true\\\\tFAIL\\\\ttrue\\\\ttrue\\\\ttrue\\\\tROLLED_BACK\\\\tNONE' ]\"}\n{\"line\":158,\"text\":\"\"}\n{\"line\":159,\"text\":\" : >\\\"$tmp\\\"\"}\n{\"line\":163,\"text\":\" printf '%s\\\\n' 'anything' >\\\"$tmp\\\"\"}\n{\"line\":164,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T5 verify 0)\\\" = \\\\\"}\n{\"line\":165,\"text\":\" $'true\\\\tNOT_APPLICABLE\\\\tfalse\\\\tfalse\\\\tnull\\\\tNO_MUTATION\\\\tNONE' ]\"}\n{\"line\":166,\"text\":\"\"}\n{\"line\":167,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":168,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"OTHER\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":169,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":170,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T6 change 0)\\\" = \\\\\"}\n{\"line\":171,\"text\":\" $'false\\\\tUNKNOWN\\\\tunknown\\\\tunknown\\\\tnull\\\\tUNKNOWN\\\\tINVALID_CONTRACT:ValueError' ]\"}\n{\"line\":172,\"text\":\"\"}\n{\"line\":173,\"text\":\" printf '%s\\\\n' \\\\\"}\n{\"line\":174,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T7\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":175,\"text\":\" 'HOMELAB_RESULT_CONTRACT={\\\"version\\\":1,\\\"command_id\\\":\\\"T7\\\",\\\"status\\\":\\\"OK\\\",\\\"changes_made\\\":true,\\\"rollback_started\\\":false,\\\"rollback_restored\\\":null}' \\\\\"}\n{\"line\":176,\"text\":\" >\\\"$tmp\\\"\"}\n{\"line\":177,\"text\":\" [ \\\"$(read_mutation_contract \\\"$tmp\\\" T7 change 0)\\\" = \\\\\"}\n{\"line\":178,\"text\":\" $'false\\\\tUNKNOWN\\\\tunknown\\\\tunknown\\\\tnull\\\\tUNKNOWN\\\\tMULTIPLE_CONTRACTS' ]\"}\n{\"line\":179,\"text\":\"\"}\n{\"line\":180,\"text\":\" echo 'SELF_TEST=PASS'\"}\n{\"line\":590,\"text\":\" sanitized_sha,\"}\n{\"line\":591,\"text\":\" run_started,\"}\n{\"line\":592,\"text\":\" repeat_blocked,\"}\n{\"line\":593,\"text\":\" block_reason,\"}\n{\"line\":594,\"text\":\" change_declared,\"}\n{\"line\":595,\"text\":\" result_contract_valid,\"}\n{\"line\":596,\"text\":\" contract_status,\"}\n{\"line\":597,\"text\":\" changes_made,\"}\n{\"line\":598,\"text\":\" rollback_started,\"}\n{\"line\":599,\"text\":\" rollback_restored,\"}\n{\"line\":600,\"text\":\" mutation_outcome,\"}\n{\"line\":601,\"text\":\" result_contract_error,\"}\n{\"line\":602,\"text\":\" command_rc,\"}\n{\"line\":603,\"text\":\") = sys.argv[1:]\"}\n{\"line\":604,\"text\":\"\"}\n{\"line\":605,\"text\":\"\"}\n{\"line\":606,\"text\":\"def optional_bool(value: str):\"}\n{\"line\":645,\"text\":\" \\\"command_sha256\\\": command_sha,\"}\n{\"line\":646,\"text\":\" \\\"duplicate_failed_command_blocked\\\": repeat_blocked == \\\"true\\\",\"}\n{\"line\":647,\"text\":\" \\\"block_reason\\\": block_reason or None,\"}\n{\"line\":648,\"text\":\" \\\"execution_started\\\": run_started == \\\"true\\\",\"}\n{\"line\":649,\"text\":\" \\\"change_declared\\\": change_declared == \\\"true\\\",\"}\n{\"line\":650,\"text\":\" \\\"result_contract_valid\\\": result_contract_valid == \\\"true\\\",\"}\n{\"line\":651,\"text\":\" \\\"result_contract_status\\\": (\"}\n{\"line\":652,\"text\":\" None\"}\n{\"line\":653,\"text\":\" if contract_status in {\\\"\\\", \\\"UNKNOWN\\\", \\\"NOT_APPLICABLE\\\"}\"}\n{\"line\":654,\"text\":\" else contract_status\"}\n{\"line\":655,\"text\":\" ),\"}\n{\"line\":656,\"text\":\" \\\"result_contract_error\\\": (\"}\n{\"line\":657,\"text\":\" None\"}\n{\"line\":658,\"text\":\" if result_contract_error == \\\"NONE\\\"\"}\n{\"line\":659,\"text\":\" else result_contract_error\"}\n{\"line\":660,\"text\":\" ),\"}\n{\"line\":661,\"text\":\" \\\"command_rc\\\": int(command_rc) if command_rc else None,\"}\n{\"line\":662,\"text\":\" \\\"changes_made\\\": optional_bool(changes_made),\"}\n{\"line\":663,\"text\":\" \\\"rollback_started\\\": optional_bool(rollback_started),\"}\n{\"line\":664,\"text\":\" \\\"rollback_restored\\\": optional_bool(rollback_restored),\"}\n{\"line\":665,\"text\":\" \\\"mutation_outcome\\\": mutation_outcome,\"}\n{\"line\":666,\"text\":\" \\\"sanitized\\\": True,\"}\n{\"line\":667,\"text\":\" \\\"secrets_included\\\": False,\"}\n{\"line\":668,\"text\":\" \\\"private_addresses_included\\\": False,\"}\n{\"line\":669,\"text\":\" \\\"raw_evidence_retained_locally\\\": True,\"}\n{\"line\":670,\"text\":\" \\\"raw_evidence_sha256\\\": raw_sha,\"}\nRUNNER_CONTRACT_VALIDATOR_SOURCE_END\nRUNNER_SELECTED_LINE_COUNT=203\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"NEWFI-260907-PORTAL200-APPLY3FAILRCA1\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\nNEWFI56_END\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index 188ad8eb..577f77ef 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,15 +1,15 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3RCA1 +COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3FAILRCA1 STATUS=OK RC=0 HOST=pve01 MODE=read-only -COMPONENT=newfi-portal200-apply3-rca +COMPONENT=newfi-portal200-apply3-failure-contract-rca REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=ed9e63a542099ec6e649d45aba789c8193600c8fb6ba0cb52d92e160c1ba5d45 +COMMAND_SHA256=01c670ca07e27a1cb55525fe1ea9c027122da3bc03abe444f5de750d8c345a62 DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true CHANGE_DECLARED=false @@ -24,30 +24,22 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=ddd2941f326ba6cecf9755d25f37bcfd721945dbc4f845a57d0ae557d3a70855 -SANITIZED_OUTPUT_SHA256=ddd2941f326ba6cecf9755d25f37bcfd721945dbc4f845a57d0ae557d3a70855 +RAW_EVIDENCE_SHA256=b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12 +SANITIZED_OUTPUT_SHA256=b9821329659ff4c37416b4128e0aa02533077613a225ffa1325ae4372ca38b12 OUTPUT_BEGIN -NEWFI55_BEGIN -COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3RCA1 -RCA_TARGET_FAILED_COMMAND=NEWFI-260907-PORTAL200-APPLY3 -PORTAL200_ROADMAP_REMAINS=22 -RCA_MUTATION_SCOPE=NONE_READ_ONLY -RCA_WRAPPER_BYTES=669 -RCA_WRAPPER_SHA256=dec036ea985e75d776b2de8c2bede77fe4b4aafa5da33648b2a6b5f79f3dec30 -RCA_WRAPPER_SELECTED_LINE_COUNT=4 -RCA_WRAPPER_SELECTED_BEGIN -COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3 -COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3 -STATUS=FAIL -RC=76 -RCA_WRAPPER_SELECTED_END -RCA_GIT_STATE={"branch":"implementation/newfi-closed-mvp-20260906","clean":true,"head":"06bab5acd124e768f70305b3d7eca2f595871890","remote":"06bab5acd124e768f70305b3d7eca2f595871890","status_lines":[]} -RCA_STAGING_STATE={"application":{"boardActive":"0","boardUrl":"http://newfi-staging.gram1.ru","error_count":8,"error_max_id":40,"indexRoute":"portal/"},"hostname":"newfi-staging","new_errors":[],"source":{"controller":{"bytes":247,"sha256":"53909e753ea5a011550fd280ad1c342a74ca9949be092dfbd95244243cae92f3"},"service":null,"templates_xml":{"bytes":1461,"sha256":"c29c04f8b937284e821c87957653e87c2f6ac014fac30648a0f6b18e84392adf"}},"templates":[{"bytes":1274,"css_marker":0,"html_marker":0,"sha256":"1f484c8cf6bdeda8fda2974abf8a57f8cc7453fe2a779af7c735afa3b73aa741","style_id":0,"title":"newfi_portal"}]} -RCA_PROD_STATE={"application":{"boardActive":"1","boardUrl":"https://newfi.ru","error_count":0,"error_max_id":0,"indexRoute":"portal/"},"hostname":"newfi-prod","new_errors":[],"source":{"controller":{"bytes":247,"sha256":"53909e753ea5a011550fd280ad1c342a74ca9949be092dfbd95244243cae92f3"},"service":null,"templates_xml":{"bytes":1461,"sha256":"c29c04f8b937284e821c87957653e87c2f6ac014fac30648a0f6b18e84392adf"}},"templates":[{"bytes":1274,"css_marker":0,"html_marker":0,"sha256":"1f484c8cf6bdeda8fda2974abf8a57f8cc7453fe2a779af7c735afa3b73aa741","style_id":0,"title":"newfi_portal"}]} -RCA_STATE_SUMMARY={"clean_old_prestate":true,"git_clean":true,"git_old_head":true,"prod_error_max":0,"prod_source":"OLD","prod_templates":"OLD","staging_error_max":40,"staging_source":"OLD","staging_templates":"OLD"} -RCA_RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d -RCA_RUNNER_BYTES=21321 -RCA_RUNNER_CONTRACT_SOURCE_BEGIN +NEWFI56_BEGIN +COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3FAILRCA1 +MUTATION_SCOPE=NONE_READ_ONLY +WRAPPER_BYTES=669 +WRAPPER_SHA256=dec036ea985e75d776b2de8c2bede77fe4b4aafa5da33648b2a6b5f79f3dec30 +APPLY3_SELECTED_OUTPUT_BEGIN +APPLY3_SELECTED_OUTPUT_END +APPLY3_SELECTED_LINE_COUNT=0 +RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d +RUNNER_BYTES=21321 +RUNNER_CONTRACT_VALIDATOR_SOURCE_BEGIN +{"line":12,"text":"command_rc = int(command_rc)"} +{"line":13,"text":""} {"line":14,"text":"result = {"} {"line":15,"text":" \"valid\": True,"} {"line":16,"text":" \"status\": \"NOT_APPLICABLE\","} @@ -57,6 +49,8 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":20,"text":" \"mutation_outcome\": \"NO_MUTATION\","} {"line":21,"text":" \"error\": \"NONE\","} {"line":22,"text":"}"} +{"line":23,"text":""} +{"line":24,"text":"if mode == \"change\":"} {"line":25,"text":" result = {"} {"line":26,"text":" \"valid\": False,"} {"line":27,"text":" \"status\": \"UNKNOWN\","} @@ -70,6 +64,10 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":35,"text":" lines = Path(raw_path).read_bytes().decode("} {"line":36,"text":" \"utf-8\","} {"line":37,"text":" errors=\"replace\","} +{"line":38,"text":" ).splitlines()"} +{"line":39,"text":" payloads = ["} +{"line":43,"text":" ]"} +{"line":44,"text":" if len(payloads) == 1:"} {"line":45,"text":" try:"} {"line":46,"text":" document = json.loads(payloads[0])"} {"line":47,"text":" if not isinstance(document, dict):"} @@ -126,6 +124,7 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":98,"text":" outcome = \"ROLLBACK_FAILED\""} {"line":99,"text":" else:"} {"line":100,"text":" outcome = \"ROLLBACK_UNKNOWN\""} +{"line":101,"text":""} {"line":102,"text":" result = {"} {"line":103,"text":" \"valid\": True,"} {"line":104,"text":" \"status\": status,"} @@ -140,6 +139,12 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":113,"text":" ),"} {"line":114,"text":" \"mutation_outcome\": outcome,"} {"line":115,"text":" \"error\": \"NONE\","} +{"line":116,"text":" }"} +{"line":117,"text":" except Exception as exc:"} +{"line":118,"text":" result[\"error\"] = ("} +{"line":119,"text":" \"INVALID_CONTRACT:\" + type(exc).__name__"} +{"line":122,"text":" result[\"error\"] = \"MULTIPLE_CONTRACTS\""} +{"line":123,"text":""} {"line":124,"text":"print(\"\\t\".join(["} {"line":125,"text":" str(result[\"valid\"]).lower(),"} {"line":126,"text":" result[\"status\"],"} @@ -149,6 +154,11 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":130,"text":" result[\"mutation_outcome\"],"} {"line":131,"text":" result[\"error\"],"} {"line":132,"text":"]))"} +{"line":133,"text":"PY_CONTRACT"} +{"line":134,"text":"}"} +{"line":135,"text":""} +{"line":137,"text":" local tmp"} +{"line":138,"text":" tmp=\"$(mktemp)\""} {"line":139,"text":" trap 'rm -f \"$tmp\"' RETURN"} {"line":140,"text":""} {"line":141,"text":" printf '%s\\n' \\"} @@ -168,6 +178,10 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":155,"text":" >\"$tmp\""} {"line":156,"text":" [ \"$(read_mutation_contract \"$tmp\" T3 change 1)\" = \\"} {"line":157,"text":" $'true\\tFAIL\\ttrue\\ttrue\\ttrue\\tROLLED_BACK\\tNONE' ]"} +{"line":158,"text":""} +{"line":159,"text":" : >\"$tmp\""} +{"line":163,"text":" printf '%s\\n' 'anything' >\"$tmp\""} +{"line":164,"text":" [ \"$(read_mutation_contract \"$tmp\" T5 verify 0)\" = \\"} {"line":165,"text":" $'true\\tNOT_APPLICABLE\\tfalse\\tfalse\\tnull\\tNO_MUTATION\\tNONE' ]"} {"line":166,"text":""} {"line":167,"text":" printf '%s\\n' \\"} @@ -182,6 +196,12 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":176,"text":" >\"$tmp\""} {"line":177,"text":" [ \"$(read_mutation_contract \"$tmp\" T7 change 0)\" = \\"} {"line":178,"text":" $'false\\tUNKNOWN\\tunknown\\tunknown\\tnull\\tUNKNOWN\\tMULTIPLE_CONTRACTS' ]"} +{"line":179,"text":""} +{"line":180,"text":" echo 'SELF_TEST=PASS'"} +{"line":590,"text":" sanitized_sha,"} +{"line":591,"text":" run_started,"} +{"line":592,"text":" repeat_blocked,"} +{"line":593,"text":" block_reason,"} {"line":594,"text":" change_declared,"} {"line":595,"text":" result_contract_valid,"} {"line":596,"text":" contract_status,"} @@ -191,6 +211,24 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":600,"text":" mutation_outcome,"} {"line":601,"text":" result_contract_error,"} {"line":602,"text":" command_rc,"} +{"line":603,"text":") = sys.argv[1:]"} +{"line":604,"text":""} +{"line":605,"text":""} +{"line":606,"text":"def optional_bool(value: str):"} +{"line":645,"text":" \"command_sha256\": command_sha,"} +{"line":646,"text":" \"duplicate_failed_command_blocked\": repeat_blocked == \"true\","} +{"line":647,"text":" \"block_reason\": block_reason or None,"} +{"line":648,"text":" \"execution_started\": run_started == \"true\","} +{"line":649,"text":" \"change_declared\": change_declared == \"true\","} +{"line":650,"text":" \"result_contract_valid\": result_contract_valid == \"true\","} +{"line":651,"text":" \"result_contract_status\": ("} +{"line":652,"text":" None"} +{"line":653,"text":" if contract_status in {\"\", \"UNKNOWN\", \"NOT_APPLICABLE\"}"} +{"line":654,"text":" else contract_status"} +{"line":655,"text":" ),"} +{"line":656,"text":" \"result_contract_error\": ("} +{"line":657,"text":" None"} +{"line":658,"text":" if result_contract_error == \"NONE\""} {"line":659,"text":" else result_contract_error"} {"line":660,"text":" ),"} {"line":661,"text":" \"command_rc\": int(command_rc) if command_rc else None,"} @@ -200,9 +238,13 @@ RCA_RUNNER_CONTRACT_SOURCE_BEGIN {"line":665,"text":" \"mutation_outcome\": mutation_outcome,"} {"line":666,"text":" \"sanitized\": True,"} {"line":667,"text":" \"secrets_included\": False,"} -RCA_RUNNER_CONTRACT_SOURCE_END -HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"NEWFI-260907-PORTAL200-APPLY3RCA1","rollback_restored":null,"rollback_started":false,"status":"OK","version":1} -NEWFI55_END +{"line":668,"text":" \"private_addresses_included\": False,"} +{"line":669,"text":" \"raw_evidence_retained_locally\": True,"} +{"line":670,"text":" \"raw_evidence_sha256\": raw_sha,"} +RUNNER_CONTRACT_VALIDATOR_SOURCE_END +RUNNER_SELECTED_LINE_COUNT=203 +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"NEWFI-260907-PORTAL200-APPLY3FAILRCA1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} +NEWFI56_END OUTPUT_END CHAT_OUTPUT_END