diff --git a/runtime/history/HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z.json b/runtime/history/HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z.json new file mode 100644 index 0000000..8ff0555 --- /dev/null +++ b/runtime/history/HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "verify", + "component": "skladchik-handoff-mutation-contract-ro", + "started_at_utc": "2026-08-05T13:43:23Z", + "finished_at_utc": "2026-08-05T13:43:24Z", + "reference_register_checked": true, + "reference_sha256": "5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e", + "error_register_checked": true, + "error_register_sha256": "24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83", + "command_sha256": "a3b0c734b66148908c75cebaabbc4fd76c8102414584c20c6fdf04a6ef01f0b4", + "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": "77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5", + "sanitized_output_sha256": "77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "HOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"output_truncated_in_json\":false,\"rc\":0,\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\n{\"adapter\":{\"basename\":\"homelab-command-adapter\",\"mode_risk_contract\":{\"candidate_values\":[\"HIGH\",\"READ_ONLY\",\"REVERSIBLE\",\"available\",\"change\",\"change capsule must declare production change\",\"change capsule requires available rollback\",\"change capsule risk must be REVERSIBLE or HIGH\",\"invalid mode\",\"invalid risk\",\"non-change capsule cannot declare changes\",\"non-change capsule risk must be READ_ONLY\",\"production\"],\"comparisons\":[{\"line\":370,\"names\":[\"mode\"],\"segment_sha256\":\"fb9813b54c11137bed7aedcae743fc0a0db019a66562c6f3380fce1a69f76370\",\"text\":\"if mode not in ALLOWED_MODES:\\n raise AdapterError(\\\"invalid mode\\\")\",\"values\":[\"invalid mode\"]},{\"line\":384,\"names\":[\"risk\"],\"segment_sha256\":\"e49cc412f4f63f1515bfc021820cb8d7f9640f950ea9b8a0f13dad14a60d5839\",\"text\":\"if risk not in ALLOWED_RISKS:\\n raise AdapterError(\\\"invalid risk\\\")\",\"values\":[\"invalid risk\"]},{\"line\":386,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"bb56e08695ce4980c221165b414b27f3afc246b8b5c1d3402c1c831292acef5a\",\"text\":\"if mode == \\\"change\\\" and risk not in {\\\"REVERSIBLE\\\", \\\"HIGH\\\"}:\\n raise AdapterError(\\\"change capsule risk must be REVERSIBLE or HIGH\\\")\",\"values\":[\"HIGH\",\"REVERSIBLE\",\"change\",\"change capsule risk must be REVERSIBLE or HIGH\"]},{\"line\":386,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"1c673162449940fc60421bc5517f24f7a30580c824b6dfb0de885cd7b98650cb\",\"text\":\"mode == \\\"change\\\" and risk not in {\\\"REVERSIBLE\\\", \\\"HIGH\\\"}\",\"values\":[\"HIGH\",\"REVERSIBLE\",\"change\"]},{\"line\":386,\"names\":[\"mode\"],\"segment_sha256\":\"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69\",\"text\":\"mode == \\\"change\\\"\",\"values\":[\"change\"]},{\"line\":386,\"names\":[\"risk\"],\"segment_sha256\":\"724ee6c7d954e249f31d377b059766cc67b75131513b547c93479821daff1665\",\"text\":\"risk not in {\\\"REVERSIBLE\\\", \\\"HIGH\\\"}\",\"values\":[\"HIGH\",\"REVERSIBLE\"]},{\"line\":388,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"c7c3a84d312747700b4f14f46c2d4b5031e7cbcd8cf567c736a690d6d377ce84\",\"text\":\"if mode != \\\"change\\\" and risk != \\\"READ_ONLY\\\":\\n raise AdapterError(\\\"non-change capsule risk must be READ_ONLY\\\")\",\"values\":[\"READ_ONLY\",\"change\",\"non-change capsule risk must be READ_ONLY\"]},{\"line\":388,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"434a09e2c0c02c095361b91cc1e32ab1bb1ffe4dae45c65b541d010268040e03\",\"text\":\"mode != \\\"change\\\" and risk != \\\"READ_ONLY\\\"\",\"values\":[\"READ_ONLY\",\"change\"]},{\"line\":388,\"names\":[\"mode\"],\"segment_sha256\":\"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce\",\"text\":\"mode != \\\"change\\\"\",\"values\":[\"change\"]},{\"line\":388,\"names\":[\"risk\"],\"segment_sha256\":\"79f7afe950f69ed28d3f9245007eb96ade840ed1e6b3dbe1b06c2ff5d55038e1\",\"text\":\"risk != \\\"READ_ONLY\\\"\",\"values\":[\"READ_ONLY\"]},{\"line\":399,\"names\":[\"mode\"],\"segment_sha256\":\"d640c7dc4427bd639bf28465290f4701b93d1fddd4adee8a03f1d80ce32eb387\",\"text\":\"if mode != \\\"change\\\" and any(flags.values()):\\n raise AdapterError(\\n \\\"non-change capsule cannot declare changes\\\"\\n )\",\"values\":[\"change\",\"non-change capsule cannot declare changes\"]},{\"line\":399,\"names\":[\"mode\"],\"segment_sha256\":\"266d98ea980186e8471babd7f4c560a932d94a83be926a459beaed430da7dc84\",\"text\":\"mode != \\\"change\\\" and any(flags.values())\",\"values\":[\"change\"]},{\"line\":399,\"names\":[\"mode\"],\"segment_sha256\":\"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce\",\"text\":\"mode != \\\"change\\\"\",\"values\":[\"change\"]},{\"line\":403,\"names\":[\"mode\"],\"segment_sha256\":\"c24b94f6049271719b2ea5316cfc4d72d3cef3c615462c5648b24974163c497a\",\"text\":\"if mode == \\\"change\\\" and not flags[\\\"production\\\"]:\\n raise AdapterError(\\n \\\"change capsule must declare production change\\\"\\n )\",\"values\":[\"change\",\"change capsule must declare production change\",\"production\"]},{\"line\":403,\"names\":[\"mode\"],\"segment_sha256\":\"f0c2605aac2630fd54fda61abe05546ff3d3d977c4a6a50125e020869a49301a\",\"text\":\"mode == \\\"change\\\" and not flags[\\\"production\\\"]\",\"values\":[\"change\",\"production\"]},{\"line\":403,\"names\":[\"mode\"],\"segment_sha256\":\"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69\",\"text\":\"mode == \\\"change\\\"\",\"values\":[\"change\"]}],\"raises\":[{\"line\":371,\"segment_sha256\":\"6d78e0909f5bb1c43cef5c9bc042720485fd0fbcb2762ccf45b7ecae433a904b\",\"text\":\"raise AdapterError(\\\"invalid mode\\\")\"},{\"line\":385,\"segment_sha256\":\"87216e6143dce952e5941a434e807e0a5ed4f39b1e04aca99176a8aa6453e1ad\",\"text\":\"raise AdapterError(\\\"invalid risk\\\")\"},{\"line\":387,\"segment_sha256\":\"43098cc02c674830f07b2d9438e5a31307585cf955039af501a23b8f05600037\",\"text\":\"raise AdapterError(\\\"change capsule risk must be REVERSIBLE or HIGH\\\")\"},{\"line\":389,\"segment_sha256\":\"a00c40ee846c32cb3b5198553cb60d4967d4ea2b06f65174fd436ca696009f82\",\"text\":\"raise AdapterError(\\\"non-change capsule risk must be READ_ONLY\\\")\"},{\"line\":542,\"segment_sha256\":\"e4509eefed0a60ced14742d43e40dd528988c46b11c81a162eaf1b97b5c4969c\",\"text\":\"raise AdapterError(\\\"invalid payload mode\\\")\"}]},\"process_sites\":[{\"call\":\"subprocess.run\",\"line\":664,\"names\":[],\"segment_sha256\":\"fbe36f5d1ed7b23d545f105135de2993138aa4a8dafc9f5419d7c37b36deebae\",\"stderr\":\"subprocess.PIPE\",\"stdin\":\"subprocess.DEVNULL\",\"stdout\":\"subprocess.PIPE\",\"text\":\"subprocess.run(\\n args,\\n stdin=subprocess.DEVNULL,\\n stdout=subprocess.PIPE,\\n stderr=subprocess.PIPE,\\n text=True,\\n check=False,\\n timeout=timeout,\\n env=(SAFE_ENV if env is None else env),\\n )\"},{\"call\":\"subprocess.Popen\",\"line\":1626,\"names\":[],\"segment_sha256\":\"90bb736720d2877f6704459828dc5551619ba00834a4660e9ed9c7f86e05b8c6\",\"stderr\":\"subprocess.STDOUT\",\"stdin\":\"subprocess.DEVNULL\",\"stdout\":\"handle\",\"text\":\"subprocess.Popen(\\n [\\n sys.executable,\\n \\\"-B\\\",\\n str(Path(__file__).resolve()),\\n \\\"--worker\\\",\\n short_id,\\n ],\\n stdin=subprocess.DEVNULL,\\n stdout=handle,\\n stderr=subprocess.STDOUT,\\n env=SAFE_ENV,\\n start_new_session=True,\\n close_fds=True,\\n )\"},{\"call\":\"subprocess.Popen\",\"line\":2056,\"names\":[],\"segment_sha256\":\"4582da2d6b8e31108deedee5a5d6b877788db5da0f6d52120a605d76d0037d97\",\"stderr\":\"subprocess.STDOUT\",\"stdin\":\"subprocess.DEVNULL\",\"stdout\":\"subprocess.PIPE\",\"text\":\"subprocess.Popen(\\n args,\\n stdin=subprocess.DEVNULL,\\n stdout=subprocess.PIPE,\\n stderr=subprocess.STDOUT,\\n text=True,\\n env=environment,\\n start_new_session=True,\\n close_fds=True,\\n )\"}],\"sha256\":\"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d\"},\"analysis_ready\":true,\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"next_action\":\"BUILD_SHA_GUARDED_SECRET_HANDOFF_TRANSACTION\",\"output_truncated_in_json\":false,\"rc\":0,\"read_only\":true,\"required_transaction_guards\":{\"atomic_replace\":true,\"automatic_exact_rollback\":true,\"byte_for_byte_backup\":true,\"candidate_compile_and_selftest\":true,\"candidate_in_temporary_directory\":true,\"expected_sha_preconditions\":true,\"read_exact_current_sources\":true,\"secret_never_in_capsule_argv_output_or_evidence\":true,\"service_health_verification\":true},\"rollback_restored\":null,\"rollback_started\":false,\"root_cause_classification\":\"MUTATION_CAPSULE_AND_STDIN_CONTRACT_CAPTURED\",\"runner_candidates\":[],\"schema\":1,\"status\":\"OK\"}\n" +} diff --git a/runtime/history/HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z.txt b/runtime/history/HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z.txt new file mode 100644 index 0000000..1a04250 --- /dev/null +++ b/runtime/history/HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z.txt @@ -0,0 +1,34 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z +STATUS=OK +RC=0 +HOST=pve01 +MODE=verify +COMPONENT=skladchik-handoff-mutation-contract-ro +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83 +COMMAND_SHA256=a3b0c734b66148908c75cebaabbc4fd76c8102414584c20c6fdf04a6ef01f0b4 +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=77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5 +SANITIZED_OUTPUT_SHA256=77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5 +OUTPUT_BEGIN +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z","command_rc":0,"mutation_outcome":"NO_MUTATION","output_truncated_in_json":false,"rc":0,"rollback_restored":null,"rollback_started":false,"status":"OK","version":1} +{"adapter":{"basename":"homelab-command-adapter","mode_risk_contract":{"candidate_values":["HIGH","READ_ONLY","REVERSIBLE","available","change","change capsule must declare production change","change capsule requires available rollback","change capsule risk must be REVERSIBLE or HIGH","invalid mode","invalid risk","non-change capsule cannot declare changes","non-change capsule risk must be READ_ONLY","production"],"comparisons":[{"line":370,"names":["mode"],"segment_sha256":"fb9813b54c11137bed7aedcae743fc0a0db019a66562c6f3380fce1a69f76370","text":"if mode not in ALLOWED_MODES:\n raise AdapterError(\"invalid mode\")","values":["invalid mode"]},{"line":384,"names":["risk"],"segment_sha256":"e49cc412f4f63f1515bfc021820cb8d7f9640f950ea9b8a0f13dad14a60d5839","text":"if risk not in ALLOWED_RISKS:\n raise AdapterError(\"invalid risk\")","values":["invalid risk"]},{"line":386,"names":["mode","risk"],"segment_sha256":"bb56e08695ce4980c221165b414b27f3afc246b8b5c1d3402c1c831292acef5a","text":"if mode == \"change\" and risk not in {\"REVERSIBLE\", \"HIGH\"}:\n raise AdapterError(\"change capsule risk must be REVERSIBLE or HIGH\")","values":["HIGH","REVERSIBLE","change","change capsule risk must be REVERSIBLE or HIGH"]},{"line":386,"names":["mode","risk"],"segment_sha256":"1c673162449940fc60421bc5517f24f7a30580c824b6dfb0de885cd7b98650cb","text":"mode == \"change\" and risk not in {\"REVERSIBLE\", \"HIGH\"}","values":["HIGH","REVERSIBLE","change"]},{"line":386,"names":["mode"],"segment_sha256":"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69","text":"mode == \"change\"","values":["change"]},{"line":386,"names":["risk"],"segment_sha256":"724ee6c7d954e249f31d377b059766cc67b75131513b547c93479821daff1665","text":"risk not in {\"REVERSIBLE\", \"HIGH\"}","values":["HIGH","REVERSIBLE"]},{"line":388,"names":["mode","risk"],"segment_sha256":"c7c3a84d312747700b4f14f46c2d4b5031e7cbcd8cf567c736a690d6d377ce84","text":"if mode != \"change\" and risk != \"READ_ONLY\":\n raise AdapterError(\"non-change capsule risk must be READ_ONLY\")","values":["READ_ONLY","change","non-change capsule risk must be READ_ONLY"]},{"line":388,"names":["mode","risk"],"segment_sha256":"434a09e2c0c02c095361b91cc1e32ab1bb1ffe4dae45c65b541d010268040e03","text":"mode != \"change\" and risk != \"READ_ONLY\"","values":["READ_ONLY","change"]},{"line":388,"names":["mode"],"segment_sha256":"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce","text":"mode != \"change\"","values":["change"]},{"line":388,"names":["risk"],"segment_sha256":"79f7afe950f69ed28d3f9245007eb96ade840ed1e6b3dbe1b06c2ff5d55038e1","text":"risk != \"READ_ONLY\"","values":["READ_ONLY"]},{"line":399,"names":["mode"],"segment_sha256":"d640c7dc4427bd639bf28465290f4701b93d1fddd4adee8a03f1d80ce32eb387","text":"if mode != \"change\" and any(flags.values()):\n raise AdapterError(\n \"non-change capsule cannot declare changes\"\n )","values":["change","non-change capsule cannot declare changes"]},{"line":399,"names":["mode"],"segment_sha256":"266d98ea980186e8471babd7f4c560a932d94a83be926a459beaed430da7dc84","text":"mode != \"change\" and any(flags.values())","values":["change"]},{"line":399,"names":["mode"],"segment_sha256":"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce","text":"mode != \"change\"","values":["change"]},{"line":403,"names":["mode"],"segment_sha256":"c24b94f6049271719b2ea5316cfc4d72d3cef3c615462c5648b24974163c497a","text":"if mode == \"change\" and not flags[\"production\"]:\n raise AdapterError(\n \"change capsule must declare production change\"\n )","values":["change","change capsule must declare production change","production"]},{"line":403,"names":["mode"],"segment_sha256":"f0c2605aac2630fd54fda61abe05546ff3d3d977c4a6a50125e020869a49301a","text":"mode == \"change\" and not flags[\"production\"]","values":["change","production"]},{"line":403,"names":["mode"],"segment_sha256":"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69","text":"mode == \"change\"","values":["change"]}],"raises":[{"line":371,"segment_sha256":"6d78e0909f5bb1c43cef5c9bc042720485fd0fbcb2762ccf45b7ecae433a904b","text":"raise AdapterError(\"invalid mode\")"},{"line":385,"segment_sha256":"87216e6143dce952e5941a434e807e0a5ed4f39b1e04aca99176a8aa6453e1ad","text":"raise AdapterError(\"invalid risk\")"},{"line":387,"segment_sha256":"43098cc02c674830f07b2d9438e5a31307585cf955039af501a23b8f05600037","text":"raise AdapterError(\"change capsule risk must be REVERSIBLE or HIGH\")"},{"line":389,"segment_sha256":"a00c40ee846c32cb3b5198553cb60d4967d4ea2b06f65174fd436ca696009f82","text":"raise AdapterError(\"non-change capsule risk must be READ_ONLY\")"},{"line":542,"segment_sha256":"e4509eefed0a60ced14742d43e40dd528988c46b11c81a162eaf1b97b5c4969c","text":"raise AdapterError(\"invalid payload mode\")"}]},"process_sites":[{"call":"subprocess.run","line":664,"names":[],"segment_sha256":"fbe36f5d1ed7b23d545f105135de2993138aa4a8dafc9f5419d7c37b36deebae","stderr":"subprocess.PIPE","stdin":"subprocess.DEVNULL","stdout":"subprocess.PIPE","text":"subprocess.run(\n args,\n stdin=subprocess.DEVNULL,\n stdout=subprocess.PIPE,\n stderr=subprocess.PIPE,\n text=True,\n check=False,\n timeout=timeout,\n env=(SAFE_ENV if env is None else env),\n )"},{"call":"subprocess.Popen","line":1626,"names":[],"segment_sha256":"90bb736720d2877f6704459828dc5551619ba00834a4660e9ed9c7f86e05b8c6","stderr":"subprocess.STDOUT","stdin":"subprocess.DEVNULL","stdout":"handle","text":"subprocess.Popen(\n [\n sys.executable,\n \"-B\",\n str(Path(__file__).resolve()),\n \"--worker\",\n short_id,\n ],\n stdin=subprocess.DEVNULL,\n stdout=handle,\n stderr=subprocess.STDOUT,\n env=SAFE_ENV,\n start_new_session=True,\n close_fds=True,\n )"},{"call":"subprocess.Popen","line":2056,"names":[],"segment_sha256":"4582da2d6b8e31108deedee5a5d6b877788db5da0f6d52120a605d76d0037d97","stderr":"subprocess.STDOUT","stdin":"subprocess.DEVNULL","stdout":"subprocess.PIPE","text":"subprocess.Popen(\n args,\n stdin=subprocess.DEVNULL,\n stdout=subprocess.PIPE,\n stderr=subprocess.STDOUT,\n text=True,\n env=environment,\n start_new_session=True,\n close_fds=True,\n )"}],"sha256":"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d"},"analysis_ready":true,"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z","command_rc":0,"mutation_outcome":"NO_MUTATION","next_action":"BUILD_SHA_GUARDED_SECRET_HANDOFF_TRANSACTION","output_truncated_in_json":false,"rc":0,"read_only":true,"required_transaction_guards":{"atomic_replace":true,"automatic_exact_rollback":true,"byte_for_byte_backup":true,"candidate_compile_and_selftest":true,"candidate_in_temporary_directory":true,"expected_sha_preconditions":true,"read_exact_current_sources":true,"secret_never_in_capsule_argv_output_or_evidence":true,"service_health_verification":true},"rollback_restored":null,"rollback_started":false,"root_cause_classification":"MUTATION_CAPSULE_AND_STDIN_CONTRACT_CAPTURED","runner_candidates":[],"schema":1,"status":"OK"} + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index b73e7dc..8ff0555 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "HOMELAB-SKLADCHIK-HANDOFF-PATCH-CONTEXT-READ-ONLY-V2-20260805T131200Z", + "command_id": "HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z", "status": "OK", "rc": 0, "host": "pve01", "mode": "verify", - "component": "skladchik-handoff-patch-context-ro-v2", - "started_at_utc": "2026-08-05T13:23:53Z", - "finished_at_utc": "2026-08-05T13:23:53Z", + "component": "skladchik-handoff-mutation-contract-ro", + "started_at_utc": "2026-08-05T13:43:23Z", + "finished_at_utc": "2026-08-05T13:43:24Z", "reference_register_checked": true, "reference_sha256": "5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e", "error_register_checked": true, "error_register_sha256": "24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83", - "command_sha256": "bdbee9327f44bfcf4da9c41496257b1a350c1792ec5f354159da6621124d7f6d", + "command_sha256": "a3b0c734b66148908c75cebaabbc4fd76c8102414584c20c6fdf04a6ef01f0b4", "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": "645b443333752ee2a7900290eb7a21e410acefb1a4ed929a99c139da80dd1719", - "sanitized_output_sha256": "645b443333752ee2a7900290eb7a21e410acefb1a4ed929a99c139da80dd1719", + "raw_evidence_sha256": "77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5", + "sanitized_output_sha256": "77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "HOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-HANDOFF-PATCH-CONTEXT-READ-ONLY-V2-20260805T131200Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"output_truncated_in_json\":false,\"rc\":0,\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\n{\"active_files\":[{\"anchors\":[{\"line\":427,\"segment_sha256\":\"ba2a9f580ceb6219636a3c6a9c8e21ef038cb66dff11b5482b985947b12905bc\",\"text\":\"1 <= len(argv) <= 128\"},{\"line\":499,\"segment_sha256\":\"8bd3e09d95d346415baa0597f44086071f2798ede0476c1adfad1f3b215c8e78\",\"text\":\"len(payload) > 32\"},{\"line\":536,\"segment_sha256\":\"65bfbef8abd20d6fb32a7594441e172311729afb83b74c9a0fe65938127f7b6d\",\"text\":\"relative in payload_paths\"},{\"line\":565,\"segment_sha256\":\"46eb980bc24c778b9d23e7d87fd5be7a19fa5efb58701ee8cd9608f85b527888\",\"text\":\"total_payload > MAX_PAYLOAD_BYTES\"},{\"line\":602,\"segment_sha256\":\"15f5757fe00d2ce1ed6dda00fe692e7710cb4693f7228fb6de4bec9e5d7127b1\",\"text\":\"relative not in payload_paths\"},{\"line\":1745,\"segment_sha256\":\"191286074b0b5feeb625b5ce92a9677a514dec1fcf9e169ed3968a79517be462\",\"text\":\"runner_document.get(\\\"secrets_included\\\") is not False\"},{\"line\":1756,\"segment_sha256\":\"718c072975da02520b0011252316d9df080b88caa3ef021bad21aafd36c22597\",\"text\":\"key != \\\"argv\\\"\"},{\"line\":2891,\"segment_sha256\":\"874df6b19b74e478b27c859c5194626606613ff18b886fade606d5ba701d6de2\",\"text\":\"(\\n Path(directory) / \\\"payload\\\" / \\\"main.py\\\"\\n ).read_bytes() == payload_content\"}],\"basename\":\"homelab-command-adapter\",\"bytes\":86019,\"functions\":[{\"args\":[\"args\"],\"end\":673,\"header\":\"def run_command(\\n args: list[str],\",\"hotspot\":[{\"end\":668,\"original_sha256\":\"8d44e4eb6b769400040df651f85468ce2751903e298a7b917d0da7720d99877e\",\"start\":665,\"text\":\"665: args,\\n666: stdin=subprocess.DEVNULL,\\n667: stdout=subprocess.PIPE,\\n668: stderr=subprocess.PIPE,\"}],\"keyword_line_count\":5,\"name\":\"run_command\",\"segment_sha256\":\"ae477f09ebbf0c4b47b2def5d2e409b7a751ff9fdf5243f102c9449b4f2a26e9\",\"start\":658},{\"args\":[\"state\"],\"end\":1592,\"header\":\"def sanitize_state(state: dict[str, Any]) -> dict[str, Any]:\\n execution = state.get(\\\"execution\\\")\",\"hotspot\":[{\"end\":1568,\"original_sha256\":\"7c8ebb2ae104e19372bb498b12ef7405e9fd150a596324a214215b4dc8b13959\",\"start\":1565,\"text\":\"1565:\\n1566: evidence = state.get(\\\"evidence\\\")\\n1567: public_evidence = None\\n1568: if isinstance(evidence, dict):\"}],\"keyword_line_count\":5,\"name\":\"sanitize_state\",\"segment_sha256\":\"175e0927b3285f609b85baca34569d3a6c932cfefaa59358dcf45e3a06702ac3\",\"start\":1547},{\"args\":[\"argv\",\"payload_root\"],\"end\":1692,\"header\":\"def substitute_argv(\\n argv: list[str],\",\"hotspot\":[{\"end\":1685,\"original_sha256\":\"83a21c644a9a2942305c2d619e2225be2798ae3f0cb09f1ff49de00c636d7ff1\",\"start\":1682,\"text\":\"1682: raise AdapterError(\\n1683: \\\"payload argv escapes root\\\"\\n1684: ) from exc\\n1685: if not target.is_file() or target.is_symlink():\"}],\"keyword_line_count\":6,\"name\":\"substitute_argv\",\"segment_sha256\":\"e8ba20cbb06e9edbf9c5c450b96698680d515fc4d560889919388697f03b69a5\",\"start\":1670},{\"args\":[\"args\"],\"end\":2102,\"header\":\"def run_existing_runner(\\n args: list[str],\",\"hotspot\":[{\"end\":2058,\"original_sha256\":\"72447a50c01a068395785579cdd058a5630ed22e8f7e73851066981064ca7a04\",\"start\":2055,\"text\":\"2055:) -> subprocess.CompletedProcess[str]:\\n2056: process = subprocess.Popen(\\n2057: args,\\n2058: stdin=subprocess.DEVNULL,\"}],\"keyword_line_count\":8,\"name\":\"run_existing_runner\",\"segment_sha256\":\"485d5c01da41e1e871a9eeadde83cb97a3962adcf6ac4fee8fa74b945f338739\",\"start\":2049},{\"args\":[\"request\"],\"end\":2745,\"header\":\"def dispatch(request: dict[str, Any]) -> dict[str, Any]:\\n operation = request.get(\\\"op\\\")\",\"hotspot\":[{\"end\":2641,\"original_sha256\":\"63ea5ee14fcb5cf84b7f3921b8780888eafc16d31f6e2981e7e55c987219cba6\",\"start\":2638,\"text\":\"2638:\\n2639:def dispatch(request: dict[str, Any]) -> dict[str, Any]:\\n2640: operation = request.get(\\\"op\\\")\\n2641: if operation == \\\"health\\\":\"}],\"keyword_line_count\":23,\"name\":\"dispatch\",\"segment_sha256\":\"3e4fc40ccc43328184094336f2fbe3604cd4e1be4a2cd057dae52b8369ae5bfe\",\"start\":2639},{\"args\":[\"self\"],\"end\":2790,\"header\":\" def handle(self) -> None:\\n credentials = self.request.getsockopt(\",\"hotspot\":[{\"end\":2774,\"original_sha256\":\"09e4d28ded165a82f3fcdcf09253762a4e59749f0503489bf41099a59570ff04\",\"start\":2771,\"text\":\"2771: try:\\n2772: request = json.loads(raw)\\n2773: if not isinstance(request, dict):\\n2774: raise AdapterError(\\\"request not object\\\")\"}],\"keyword_line_count\":8,\"name\":\"handle\",\"segment_sha256\":\"794078bbd307f80c2f6640b374565fa119f03dabd1ba36a9c4d47d9b2d8865c6\",\"start\":2749}],\"mode\":\"0o755\",\"process_sites\":[{\"call\":\"stream.read\",\"keywords\":[],\"line\":197,\"segment_sha256\":\"b132f27ce56f994d404626d8bcf725db9bd3a7476b7d532089ce2a297eb1e355\",\"text\":\"stream.read(1024 * 1024)\"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"indent\",\"sort_keys\"],\"line\":204,\"segment_sha256\":\"ee60c2fbdc8f97eff20f4ac617180559018ab7343898037639e94dcff31f7882\",\"text\":\"json.dumps(\\n value,\\n ensure_ascii=False,\\n indent=2,\\n sort_keys=True,\\n )\"},{\"call\":\"json.loads\",\"keywords\":[],\"line\":245,\"segment_sha256\":\"6a36fbe7611c83cf1f9a144d11feb88410bbc002bb2aeeffc19cd9b97fdab2b4\",\"text\":\"json.loads(raw)\"},{\"call\":\"json.loads\",\"keywords\":[\"object_pairs_hook\"],\"line\":288,\"segment_sha256\":\"bf67e3bbc5d4ac5ab0d15340108bb5410b74494961d88fa35c556acbf64afbd4\",\"text\":\"json.loads(\\n raw.decode(\\\"utf-8\\\"),\\n object_pairs_hook=no_duplicates,\\n )\"},{\"call\":\"subprocess.run\",\"keywords\":[\"check\",\"env\",\"stderr\",\"stdin\",\"stdout\",\"text\",\"timeout\"],\"line\":664,\"segment_sha256\":\"fbe36f5d1ed7b23d545f105135de2993138aa4a8dafc9f5419d7c37b36deebae\",\"text\":\"subprocess.run(\\n args,\\n stdin=subprocess.DEVNULL,\\n stdout=subprocess.PIPE,\\n stderr=subprocess.PIPE,\\n text=True,\\n check=False,\\n timeout=timeout,\\n env=(SAFE_ENV if env is None else env),\\n )\"},{\"call\":\"json.loads\",\"keywords\":[],\"line\":706,\"segment_sha256\":\"49c73d21d24e89e31f7701c67025900b8b000fbdde1520e1ce4bbc04d0a543c4\",\"text\":\"json.loads(result.stdout)\"},{\"call\":\"os.read\",\"keywords\":[],\"line\":1053,\"segment_sha256\":\"69a810c779430086a44faf90bb2d5d4bbebbe3ba7a85dd8c3148ad4f9112eda4\",\"text\":\"os.read(fd, min(1024 * 1024, remaining))\"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"separators\",\"sort_keys\"],\"line\":1517,\"segment_sha256\":\"8623f260b2f2a1eaf0e8be9c2d4e8370e8567247e20f5e53556b7ac266f75403\",\"text\":\"json.dumps(\\n items,\\n ensure_ascii=False,\\n sort_keys=True,\\n separators=(\\\",\\\", \\\":\\\"),\\n )\"},{\"call\":\"subprocess.Popen\",\"keywords\":[\"close_fds\",\"env\",\"start_new_session\",\"stderr\",\"stdin\",\"stdout\"],\"line\":1626,\"segment_sha256\":\"90bb736720d2877f6704459828dc5551619ba00834a4660e9ed9c7f86e05b8c6\",\"text\":\"subprocess.Popen(\\n [\\n sys.executable,\\n \\\"-B\\\",\\n str(Path(__file__).resolve()),\\n \\\"--worker\\\",\\n short_id,\\n ],\\n \"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"separators\"],\"line\":1758,\"segment_sha256\":\"68a59ab16988992d8cb583f19eee1b55a7f8dc45e355d3655b47d522968e335e\",\"text\":\"json.dumps(\\n state[\\\"manifest\\\"][\\\"argv\\\"],\\n separators=(\\\",\\\", \\\":\\\"),\\n ensure_ascii=False,\\n )\"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"indent\",\"sort_keys\"],\"line\":1778,\"segment_sha256\":\"d31eb8080be3fc4f69b562e41f97dd655755ae2cdf26f99434c4521f86b0547c\",\"text\":\"json.dumps(\\n capsule_summary,\\n ensure_ascii=False,\\n indent=2,\\n sort_keys=True,\\n )\"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"indent\",\"sort_keys\"],\"line\":1822,\"segment_sha256\":\"e8af89f3e8da544b76204b745215223c8d2381300b60dc0c5e1baf6a4096ffdd\",\"text\":\"json.dumps(\\n meta,\\n ensure_ascii=False,\\n indent=2,\\n sort_keys=True,\\n )\"}],\"schema_fields\":[\"argv\",\"content_b64\",\"mode\",\"payload\",\"risk\"],\"sha256\":\"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d\"},{\"anchors\":[{\"line\":596,\"segment_sha256\":\"bea803e2bf945e9c5008a239e11936ecdbd8475018029010553aae5d638af370\",\"text\":\"path == \\\"/bridge/bridge.cmd\\\"\"},{\"line\":791,\"segment_sha256\":\"528504d107f4e3a9c88fb94943e594ed199c19d14b7398d0499ed62a41c176f9\",\"text\":\"path == \\\"/api/import\\\"\"}],\"basename\":\"homelab-command-portal\",\"bytes\":39936,\"functions\":[{\"args\":[\"request\"],\"end\":91,\"header\":\"def adapter_call(request: dict[str, Any]) -> dict[str, Any]:\\n encoded = (\",\"hotspot\":[{\"end\":46,\"original_sha256\":\"0810613963b5a41789eb5ecf131bf80b45e647dded9b35c5e68d4b9292f8a223\",\"start\":43,\"text\":\"43:\\n44:def adapter_call(request: dict[str, Any]) -> dict[str, Any]:\\n45: encoded = (\\n46: json.dumps(\"}],\"keyword_line_count\":7,\"name\":\"adapter_call\",\"segment_sha256\":\"1d4f3585656373b842054a15f1b11fb43cf9feab695b82df3ea8f5e8a693030a\",\"start\":44},{\"args\":[\"self\",\"status\",\"content_type\",\"body\"],\"end\":504,\"header\":\" def reply(\\n self,\",\"hotspot\":[{\"end\":477,\"original_sha256\":\"aaa0d62cf14511be6509347c1614c7f23cfcf9714885cb1464f9fb9d8961005b\",\"start\":474,\"text\":\"474: content_type: str,\\n475: body: bytes,\\n476: *,\\n477: headers: dict[str, str] | None = None,\"}],\"keyword_line_count\":4,\"name\":\"reply\",\"segment_sha256\":\"0be03d4b20f918f84107b98285a7d9bc750fcb4c717453a041a46ad7271bec53\",\"start\":471},{\"args\":[\"self\"],\"end\":764,\"header\":\" def do_GET(self) -> None:\\n try:\",\"hotspot\":[{\"end\":688,\"original_sha256\":\"dfa2bbf4800083be58a8dfb63301a47bcc206c21d4d158922ec232412fa4a17c\",\"start\":685,\"text\":\"685: f\\\"/r/{short_id}\\\",\\n686: headers={\\\"Set-Cookie\\\": cookie},\\n687: )\\n688: return\"}],\"keyword_line_count\":15,\"name\":\"do_GET\",\"segment_sha256\":\"e49c3c1e64918367b3f4c1d7404beed09ac2fe19b3be22c59b59e3f8c2d52881\",\"start\":553},{\"args\":[\"self\"],\"end\":907,\"header\":\" def do_POST(self) -> None:\\n try:\",\"hotspot\":[{\"end\":774,\"original_sha256\":\"9d3ee7b22c1c1a4de2f9220e8211c79b320c1f378da508e9408877a6ca0349d5\",\"start\":771,\"text\":\"771: if path == \\\"/api/enroll\\\":\\n772: body = self.read_body(512).decode(\\n773: \\\"ascii\\\",\\n774: errors=\\\"strict\\\",\"}],\"keyword_line_count\":14,\"name\":\"do_POST\",\"segment_sha256\":\"6c3b664bc61fb4bc506662a1711d99017254441864528c27da5db76254864694\",\"start\":766},{\"args\":[\"request\"],\"end\":1045,\"header\":\" def fake_adapter_call(request: dict[str, Any]) -> dict[str, Any]:\\n attempts[\\\"count\\\"] += 1\",\"hotspot\":[{\"end\":1043,\"original_sha256\":\"cfdde978ab18d008414db8e692c50d3de47ac561eadbc2d7deb81a5a1b17f669\",\"start\":1040,\"text\":\"1040:\\n1041: def fake_adapter_call(request: dict[str, Any]) -> dict[str, Any]:\\n1042: attempts[\\\"count\\\"] += 1\\n1043: if attempts[\\\"count\\\"] < 3:\"}],\"keyword_line_count\":1,\"name\":\"fake_adapter_call\",\"segment_sha256\":\"ce0cd75c856eb06926ff96b1c3d65c0ef72b6f409b5831122724d22a951fef97\",\"start\":1041}],\"mode\":\"0o755\",\"process_sites\":[{\"call\":\"json.dumps\",\"keywords\":[\"separators\",\"sort_keys\"],\"line\":46,\"segment_sha256\":\"d2796347998c58685d8dfd45d5df5fe51509645aba7a264e7dc25cb1f352c982\",\"text\":\"json.dumps(\\n request,\\n separators=(\\\",\\\", \\\":\\\"),\\n sort_keys=True,\\n )\"},{\"call\":\"json.loads\",\"keywords\":[],\"line\":81,\"segment_sha256\":\"6a36fbe7611c83cf1f9a144d11feb88410bbc002bb2aeeffc19cd9b97fdab2b4\",\"text\":\"json.loads(raw)\"},{\"call\":\"json.dumps\",\"keywords\":[\"separators\",\"sort_keys\"],\"line\":113,\"segment_sha256\":\"e2fb745bae0108aba634dcdc658da4a7423b1439f0ea5f9c725fb8338e962574\",\"text\":\"json.dumps(\\n result,\\n separators=(\\\",\\\", \\\":\\\"),\\n sort_keys=True,\\n )\"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"indent\"],\"line\":337,\"segment_sha256\":\"d6f51399c0a5250e2e7ce94f7692c5d23b32e73e2a40cfe39dfe708615296a95\",\"text\":\"json.dumps(\\n {\\n \\\"status\\\": status,\\n \\\"execution\\\": execution,\\n \\\"evidence\\\": evidence,\\n },\\n ensure_ascii=False,\\n indent=2,\\n )\"},{\"call\":\"self.rfile.read\",\"keywords\":[],\"line\":541,\"segment_sha256\":\"e88ccc84bddb9730bf85279cc75080f708954fea1522420d79deeef7f4d4022e\",\"text\":\"self.rfile.read(length)\"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"separators\",\"sort_keys\"],\"line\":569,\"segment_sha256\":\"54d09d0aed4fa5af8f08233988dff5e409332754d7767eef48c0e09cad7482d3\",\"text\":\"json.dumps(\\n {\\n \\\"status\\\": \\\"ok\\\",\\n \\\"version\\\": 3,\\n \\\"adapter\\\": result[\\\"status\\\"],\\n \\\"result_sequence\\\": recent[\\n \"},{\"call\":\"json.dumps\",\"keywords\":[\"ensure_ascii\",\"separators\",\"sort_keys\"],\"line\":745,\"segment_sha256\":\"c69d1ae04da0c2a85f4db115bb6aca05e6712ea223bec16c952e99dcc0df4f64\",\"text\":\"json.dumps(\\n state,\\n ensure_ascii=False,\\n separators=(\\\",\\\", \\\":\\\"),\\n sort_keys=True,\\n )\"}],\"schema_fields\":[\"Authorization\",\"Cookie\",\"risk\"],\"sha256\":\"97c69bd4fccf7272dadc911281c1503f411bae2dc11dac4b22b87f33d678ae52\"}],\"analysis_ready\":true,\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-HANDOFF-PATCH-CONTEXT-READ-ONLY-V2-20260805T131200Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"next_action\":\"BUILD_SHA_GUARDED_EPHEMERAL_SECRET_HANDOFF_TRANSACTION\",\"output_truncated_in_json\":false,\"projection\":{\"degraded\":false,\"safe_limit_bytes\":18000,\"strategy\":\"one_hotspot_per_target_function\"},\"rc\":0,\"read_only\":true,\"required_functions\":{\"adapter\":[\"run_command\",\"sanitize_state\",\"substitute_argv\"],\"portal\":[\"adapter_call\",\"do_POST\"]},\"rollback_restored\":null,\"rollback_started\":false,\"root_cause_classification\":\"SHA_GUARDED_COMPACT_PATCH_CONTEXT_CAPTURED\",\"schema\":1,\"status\":\"OK\",\"transaction_requirements\":{\"atomic_replace\":true,\"automatic_exact_rollback\":true,\"byte_for_byte_backup\":true,\"candidate_compile_and_selftest\":true,\"candidate_in_temporary_directory\":true,\"expected_sha_preconditions\":{\"homelab-command-adapter\":\"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d\",\"homelab-command-portal\":\"97c69bd4fccf7272dadc911281c1503f411bae2dc11dac4b22b87f33d678ae52\"},\"read_exact_current_sources\":true,\"secret_never_in_capsule_argv_output_or_evidence\":true,\"service_health_verification\":true},\"units\":[{\"active_state\":\"active\",\"exec_basename\":\"homelab-command-adapter\",\"exec_path_sha256\":\"c2e3b43f1f858c6fa265dc276d6a6a29e0cd25e4a127fbc093b8c8d9512bb739\",\"fragment_path_sha256\":\"afe4d91c280ac4e6e9999498b5f5d8b8842a1f33e30fd45d984879a6392bc045\",\"sub_state\":\"running\",\"unit\":\"homelab-command-adapter.service\"},{\"active_state\":\"active\",\"exec_basename\":\"homelab-command-portal\",\"exec_path_sha256\":\"1132c3c355ed18cdc6406935cd26a128df298f71df7f48df690c72b202ddd7be\",\"fragment_path_sha256\":\"adf87b0f1c821b17e3e2ff19cc024d783b55caf69460d01fa66f7d2579a71f5a\",\"sub_state\":\"running\",\"unit\":\"homelab-command-portal.service\"}]}\n" + "output": "HOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"output_truncated_in_json\":false,\"rc\":0,\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\n{\"adapter\":{\"basename\":\"homelab-command-adapter\",\"mode_risk_contract\":{\"candidate_values\":[\"HIGH\",\"READ_ONLY\",\"REVERSIBLE\",\"available\",\"change\",\"change capsule must declare production change\",\"change capsule requires available rollback\",\"change capsule risk must be REVERSIBLE or HIGH\",\"invalid mode\",\"invalid risk\",\"non-change capsule cannot declare changes\",\"non-change capsule risk must be READ_ONLY\",\"production\"],\"comparisons\":[{\"line\":370,\"names\":[\"mode\"],\"segment_sha256\":\"fb9813b54c11137bed7aedcae743fc0a0db019a66562c6f3380fce1a69f76370\",\"text\":\"if mode not in ALLOWED_MODES:\\n raise AdapterError(\\\"invalid mode\\\")\",\"values\":[\"invalid mode\"]},{\"line\":384,\"names\":[\"risk\"],\"segment_sha256\":\"e49cc412f4f63f1515bfc021820cb8d7f9640f950ea9b8a0f13dad14a60d5839\",\"text\":\"if risk not in ALLOWED_RISKS:\\n raise AdapterError(\\\"invalid risk\\\")\",\"values\":[\"invalid risk\"]},{\"line\":386,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"bb56e08695ce4980c221165b414b27f3afc246b8b5c1d3402c1c831292acef5a\",\"text\":\"if mode == \\\"change\\\" and risk not in {\\\"REVERSIBLE\\\", \\\"HIGH\\\"}:\\n raise AdapterError(\\\"change capsule risk must be REVERSIBLE or HIGH\\\")\",\"values\":[\"HIGH\",\"REVERSIBLE\",\"change\",\"change capsule risk must be REVERSIBLE or HIGH\"]},{\"line\":386,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"1c673162449940fc60421bc5517f24f7a30580c824b6dfb0de885cd7b98650cb\",\"text\":\"mode == \\\"change\\\" and risk not in {\\\"REVERSIBLE\\\", \\\"HIGH\\\"}\",\"values\":[\"HIGH\",\"REVERSIBLE\",\"change\"]},{\"line\":386,\"names\":[\"mode\"],\"segment_sha256\":\"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69\",\"text\":\"mode == \\\"change\\\"\",\"values\":[\"change\"]},{\"line\":386,\"names\":[\"risk\"],\"segment_sha256\":\"724ee6c7d954e249f31d377b059766cc67b75131513b547c93479821daff1665\",\"text\":\"risk not in {\\\"REVERSIBLE\\\", \\\"HIGH\\\"}\",\"values\":[\"HIGH\",\"REVERSIBLE\"]},{\"line\":388,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"c7c3a84d312747700b4f14f46c2d4b5031e7cbcd8cf567c736a690d6d377ce84\",\"text\":\"if mode != \\\"change\\\" and risk != \\\"READ_ONLY\\\":\\n raise AdapterError(\\\"non-change capsule risk must be READ_ONLY\\\")\",\"values\":[\"READ_ONLY\",\"change\",\"non-change capsule risk must be READ_ONLY\"]},{\"line\":388,\"names\":[\"mode\",\"risk\"],\"segment_sha256\":\"434a09e2c0c02c095361b91cc1e32ab1bb1ffe4dae45c65b541d010268040e03\",\"text\":\"mode != \\\"change\\\" and risk != \\\"READ_ONLY\\\"\",\"values\":[\"READ_ONLY\",\"change\"]},{\"line\":388,\"names\":[\"mode\"],\"segment_sha256\":\"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce\",\"text\":\"mode != \\\"change\\\"\",\"values\":[\"change\"]},{\"line\":388,\"names\":[\"risk\"],\"segment_sha256\":\"79f7afe950f69ed28d3f9245007eb96ade840ed1e6b3dbe1b06c2ff5d55038e1\",\"text\":\"risk != \\\"READ_ONLY\\\"\",\"values\":[\"READ_ONLY\"]},{\"line\":399,\"names\":[\"mode\"],\"segment_sha256\":\"d640c7dc4427bd639bf28465290f4701b93d1fddd4adee8a03f1d80ce32eb387\",\"text\":\"if mode != \\\"change\\\" and any(flags.values()):\\n raise AdapterError(\\n \\\"non-change capsule cannot declare changes\\\"\\n )\",\"values\":[\"change\",\"non-change capsule cannot declare changes\"]},{\"line\":399,\"names\":[\"mode\"],\"segment_sha256\":\"266d98ea980186e8471babd7f4c560a932d94a83be926a459beaed430da7dc84\",\"text\":\"mode != \\\"change\\\" and any(flags.values())\",\"values\":[\"change\"]},{\"line\":399,\"names\":[\"mode\"],\"segment_sha256\":\"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce\",\"text\":\"mode != \\\"change\\\"\",\"values\":[\"change\"]},{\"line\":403,\"names\":[\"mode\"],\"segment_sha256\":\"c24b94f6049271719b2ea5316cfc4d72d3cef3c615462c5648b24974163c497a\",\"text\":\"if mode == \\\"change\\\" and not flags[\\\"production\\\"]:\\n raise AdapterError(\\n \\\"change capsule must declare production change\\\"\\n )\",\"values\":[\"change\",\"change capsule must declare production change\",\"production\"]},{\"line\":403,\"names\":[\"mode\"],\"segment_sha256\":\"f0c2605aac2630fd54fda61abe05546ff3d3d977c4a6a50125e020869a49301a\",\"text\":\"mode == \\\"change\\\" and not flags[\\\"production\\\"]\",\"values\":[\"change\",\"production\"]},{\"line\":403,\"names\":[\"mode\"],\"segment_sha256\":\"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69\",\"text\":\"mode == \\\"change\\\"\",\"values\":[\"change\"]}],\"raises\":[{\"line\":371,\"segment_sha256\":\"6d78e0909f5bb1c43cef5c9bc042720485fd0fbcb2762ccf45b7ecae433a904b\",\"text\":\"raise AdapterError(\\\"invalid mode\\\")\"},{\"line\":385,\"segment_sha256\":\"87216e6143dce952e5941a434e807e0a5ed4f39b1e04aca99176a8aa6453e1ad\",\"text\":\"raise AdapterError(\\\"invalid risk\\\")\"},{\"line\":387,\"segment_sha256\":\"43098cc02c674830f07b2d9438e5a31307585cf955039af501a23b8f05600037\",\"text\":\"raise AdapterError(\\\"change capsule risk must be REVERSIBLE or HIGH\\\")\"},{\"line\":389,\"segment_sha256\":\"a00c40ee846c32cb3b5198553cb60d4967d4ea2b06f65174fd436ca696009f82\",\"text\":\"raise AdapterError(\\\"non-change capsule risk must be READ_ONLY\\\")\"},{\"line\":542,\"segment_sha256\":\"e4509eefed0a60ced14742d43e40dd528988c46b11c81a162eaf1b97b5c4969c\",\"text\":\"raise AdapterError(\\\"invalid payload mode\\\")\"}]},\"process_sites\":[{\"call\":\"subprocess.run\",\"line\":664,\"names\":[],\"segment_sha256\":\"fbe36f5d1ed7b23d545f105135de2993138aa4a8dafc9f5419d7c37b36deebae\",\"stderr\":\"subprocess.PIPE\",\"stdin\":\"subprocess.DEVNULL\",\"stdout\":\"subprocess.PIPE\",\"text\":\"subprocess.run(\\n args,\\n stdin=subprocess.DEVNULL,\\n stdout=subprocess.PIPE,\\n stderr=subprocess.PIPE,\\n text=True,\\n check=False,\\n timeout=timeout,\\n env=(SAFE_ENV if env is None else env),\\n )\"},{\"call\":\"subprocess.Popen\",\"line\":1626,\"names\":[],\"segment_sha256\":\"90bb736720d2877f6704459828dc5551619ba00834a4660e9ed9c7f86e05b8c6\",\"stderr\":\"subprocess.STDOUT\",\"stdin\":\"subprocess.DEVNULL\",\"stdout\":\"handle\",\"text\":\"subprocess.Popen(\\n [\\n sys.executable,\\n \\\"-B\\\",\\n str(Path(__file__).resolve()),\\n \\\"--worker\\\",\\n short_id,\\n ],\\n stdin=subprocess.DEVNULL,\\n stdout=handle,\\n stderr=subprocess.STDOUT,\\n env=SAFE_ENV,\\n start_new_session=True,\\n close_fds=True,\\n )\"},{\"call\":\"subprocess.Popen\",\"line\":2056,\"names\":[],\"segment_sha256\":\"4582da2d6b8e31108deedee5a5d6b877788db5da0f6d52120a605d76d0037d97\",\"stderr\":\"subprocess.STDOUT\",\"stdin\":\"subprocess.DEVNULL\",\"stdout\":\"subprocess.PIPE\",\"text\":\"subprocess.Popen(\\n args,\\n stdin=subprocess.DEVNULL,\\n stdout=subprocess.PIPE,\\n stderr=subprocess.STDOUT,\\n text=True,\\n env=environment,\\n start_new_session=True,\\n close_fds=True,\\n )\"}],\"sha256\":\"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d\"},\"analysis_ready\":true,\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"next_action\":\"BUILD_SHA_GUARDED_SECRET_HANDOFF_TRANSACTION\",\"output_truncated_in_json\":false,\"rc\":0,\"read_only\":true,\"required_transaction_guards\":{\"atomic_replace\":true,\"automatic_exact_rollback\":true,\"byte_for_byte_backup\":true,\"candidate_compile_and_selftest\":true,\"candidate_in_temporary_directory\":true,\"expected_sha_preconditions\":true,\"read_exact_current_sources\":true,\"secret_never_in_capsule_argv_output_or_evidence\":true,\"service_health_verification\":true},\"rollback_restored\":null,\"rollback_started\":false,\"root_cause_classification\":\"MUTATION_CAPSULE_AND_STDIN_CONTRACT_CAPTURED\",\"runner_candidates\":[],\"schema\":1,\"status\":\"OK\"}\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index aa16780..1a04250 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,15 +1,15 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=HOMELAB-SKLADCHIK-HANDOFF-PATCH-CONTEXT-READ-ONLY-V2-20260805T131200Z +COMMAND_ID=HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z STATUS=OK RC=0 HOST=pve01 MODE=verify -COMPONENT=skladchik-handoff-patch-context-ro-v2 +COMPONENT=skladchik-handoff-mutation-contract-ro REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83 -COMMAND_SHA256=bdbee9327f44bfcf4da9c41496257b1a350c1792ec5f354159da6621124d7f6d +COMMAND_SHA256=a3b0c734b66148908c75cebaabbc4fd76c8102414584c20c6fdf04a6ef01f0b4 DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true CHANGE_DECLARED=false @@ -24,11 +24,11 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=645b443333752ee2a7900290eb7a21e410acefb1a4ed929a99c139da80dd1719 -SANITIZED_OUTPUT_SHA256=645b443333752ee2a7900290eb7a21e410acefb1a4ed929a99c139da80dd1719 +RAW_EVIDENCE_SHA256=77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5 +SANITIZED_OUTPUT_SHA256=77fd1a6ce83e382a7d9873abbeaed83e449a67837978c2799713efdcb62dc8e5 OUTPUT_BEGIN -HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-HANDOFF-PATCH-CONTEXT-READ-ONLY-V2-20260805T131200Z","command_rc":0,"mutation_outcome":"NO_MUTATION","output_truncated_in_json":false,"rc":0,"rollback_restored":null,"rollback_started":false,"status":"OK","version":1} -{"active_files":[{"anchors":[{"line":427,"segment_sha256":"ba2a9f580ceb6219636a3c6a9c8e21ef038cb66dff11b5482b985947b12905bc","text":"1 <= len(argv) <= 128"},{"line":499,"segment_sha256":"8bd3e09d95d346415baa0597f44086071f2798ede0476c1adfad1f3b215c8e78","text":"len(payload) > 32"},{"line":536,"segment_sha256":"65bfbef8abd20d6fb32a7594441e172311729afb83b74c9a0fe65938127f7b6d","text":"relative in payload_paths"},{"line":565,"segment_sha256":"46eb980bc24c778b9d23e7d87fd5be7a19fa5efb58701ee8cd9608f85b527888","text":"total_payload > MAX_PAYLOAD_BYTES"},{"line":602,"segment_sha256":"15f5757fe00d2ce1ed6dda00fe692e7710cb4693f7228fb6de4bec9e5d7127b1","text":"relative not in payload_paths"},{"line":1745,"segment_sha256":"191286074b0b5feeb625b5ce92a9677a514dec1fcf9e169ed3968a79517be462","text":"runner_document.get(\"secrets_included\") is not False"},{"line":1756,"segment_sha256":"718c072975da02520b0011252316d9df080b88caa3ef021bad21aafd36c22597","text":"key != \"argv\""},{"line":2891,"segment_sha256":"874df6b19b74e478b27c859c5194626606613ff18b886fade606d5ba701d6de2","text":"(\n Path(directory) / \"payload\" / \"main.py\"\n ).read_bytes() == payload_content"}],"basename":"homelab-command-adapter","bytes":86019,"functions":[{"args":["args"],"end":673,"header":"def run_command(\n args: list[str],","hotspot":[{"end":668,"original_sha256":"8d44e4eb6b769400040df651f85468ce2751903e298a7b917d0da7720d99877e","start":665,"text":"665: args,\n666: stdin=subprocess.DEVNULL,\n667: stdout=subprocess.PIPE,\n668: stderr=subprocess.PIPE,"}],"keyword_line_count":5,"name":"run_command","segment_sha256":"ae477f09ebbf0c4b47b2def5d2e409b7a751ff9fdf5243f102c9449b4f2a26e9","start":658},{"args":["state"],"end":1592,"header":"def sanitize_state(state: dict[str, Any]) -> dict[str, Any]:\n execution = state.get(\"execution\")","hotspot":[{"end":1568,"original_sha256":"7c8ebb2ae104e19372bb498b12ef7405e9fd150a596324a214215b4dc8b13959","start":1565,"text":"1565:\n1566: evidence = state.get(\"evidence\")\n1567: public_evidence = None\n1568: if isinstance(evidence, dict):"}],"keyword_line_count":5,"name":"sanitize_state","segment_sha256":"175e0927b3285f609b85baca34569d3a6c932cfefaa59358dcf45e3a06702ac3","start":1547},{"args":["argv","payload_root"],"end":1692,"header":"def substitute_argv(\n argv: list[str],","hotspot":[{"end":1685,"original_sha256":"83a21c644a9a2942305c2d619e2225be2798ae3f0cb09f1ff49de00c636d7ff1","start":1682,"text":"1682: raise AdapterError(\n1683: \"payload argv escapes root\"\n1684: ) from exc\n1685: if not target.is_file() or target.is_symlink():"}],"keyword_line_count":6,"name":"substitute_argv","segment_sha256":"e8ba20cbb06e9edbf9c5c450b96698680d515fc4d560889919388697f03b69a5","start":1670},{"args":["args"],"end":2102,"header":"def run_existing_runner(\n args: list[str],","hotspot":[{"end":2058,"original_sha256":"72447a50c01a068395785579cdd058a5630ed22e8f7e73851066981064ca7a04","start":2055,"text":"2055:) -> subprocess.CompletedProcess[str]:\n2056: process = subprocess.Popen(\n2057: args,\n2058: stdin=subprocess.DEVNULL,"}],"keyword_line_count":8,"name":"run_existing_runner","segment_sha256":"485d5c01da41e1e871a9eeadde83cb97a3962adcf6ac4fee8fa74b945f338739","start":2049},{"args":["request"],"end":2745,"header":"def dispatch(request: dict[str, Any]) -> dict[str, Any]:\n operation = request.get(\"op\")","hotspot":[{"end":2641,"original_sha256":"63ea5ee14fcb5cf84b7f3921b8780888eafc16d31f6e2981e7e55c987219cba6","start":2638,"text":"2638:\n2639:def dispatch(request: dict[str, Any]) -> dict[str, Any]:\n2640: operation = request.get(\"op\")\n2641: if operation == \"health\":"}],"keyword_line_count":23,"name":"dispatch","segment_sha256":"3e4fc40ccc43328184094336f2fbe3604cd4e1be4a2cd057dae52b8369ae5bfe","start":2639},{"args":["self"],"end":2790,"header":" def handle(self) -> None:\n credentials = self.request.getsockopt(","hotspot":[{"end":2774,"original_sha256":"09e4d28ded165a82f3fcdcf09253762a4e59749f0503489bf41099a59570ff04","start":2771,"text":"2771: try:\n2772: request = json.loads(raw)\n2773: if not isinstance(request, dict):\n2774: raise AdapterError(\"request not object\")"}],"keyword_line_count":8,"name":"handle","segment_sha256":"794078bbd307f80c2f6640b374565fa119f03dabd1ba36a9c4d47d9b2d8865c6","start":2749}],"mode":"0o755","process_sites":[{"call":"stream.read","keywords":[],"line":197,"segment_sha256":"b132f27ce56f994d404626d8bcf725db9bd3a7476b7d532089ce2a297eb1e355","text":"stream.read(1024 * 1024)"},{"call":"json.dumps","keywords":["ensure_ascii","indent","sort_keys"],"line":204,"segment_sha256":"ee60c2fbdc8f97eff20f4ac617180559018ab7343898037639e94dcff31f7882","text":"json.dumps(\n value,\n ensure_ascii=False,\n indent=2,\n sort_keys=True,\n )"},{"call":"json.loads","keywords":[],"line":245,"segment_sha256":"6a36fbe7611c83cf1f9a144d11feb88410bbc002bb2aeeffc19cd9b97fdab2b4","text":"json.loads(raw)"},{"call":"json.loads","keywords":["object_pairs_hook"],"line":288,"segment_sha256":"bf67e3bbc5d4ac5ab0d15340108bb5410b74494961d88fa35c556acbf64afbd4","text":"json.loads(\n raw.decode(\"utf-8\"),\n object_pairs_hook=no_duplicates,\n )"},{"call":"subprocess.run","keywords":["check","env","stderr","stdin","stdout","text","timeout"],"line":664,"segment_sha256":"fbe36f5d1ed7b23d545f105135de2993138aa4a8dafc9f5419d7c37b36deebae","text":"subprocess.run(\n args,\n stdin=subprocess.DEVNULL,\n stdout=subprocess.PIPE,\n stderr=subprocess.PIPE,\n text=True,\n check=False,\n timeout=timeout,\n env=(SAFE_ENV if env is None else env),\n )"},{"call":"json.loads","keywords":[],"line":706,"segment_sha256":"49c73d21d24e89e31f7701c67025900b8b000fbdde1520e1ce4bbc04d0a543c4","text":"json.loads(result.stdout)"},{"call":"os.read","keywords":[],"line":1053,"segment_sha256":"69a810c779430086a44faf90bb2d5d4bbebbe3ba7a85dd8c3148ad4f9112eda4","text":"os.read(fd, min(1024 * 1024, remaining))"},{"call":"json.dumps","keywords":["ensure_ascii","separators","sort_keys"],"line":1517,"segment_sha256":"8623f260b2f2a1eaf0e8be9c2d4e8370e8567247e20f5e53556b7ac266f75403","text":"json.dumps(\n items,\n ensure_ascii=False,\n sort_keys=True,\n separators=(\",\", \":\"),\n )"},{"call":"subprocess.Popen","keywords":["close_fds","env","start_new_session","stderr","stdin","stdout"],"line":1626,"segment_sha256":"90bb736720d2877f6704459828dc5551619ba00834a4660e9ed9c7f86e05b8c6","text":"subprocess.Popen(\n [\n sys.executable,\n \"-B\",\n str(Path(__file__).resolve()),\n \"--worker\",\n short_id,\n ],\n "},{"call":"json.dumps","keywords":["ensure_ascii","separators"],"line":1758,"segment_sha256":"68a59ab16988992d8cb583f19eee1b55a7f8dc45e355d3655b47d522968e335e","text":"json.dumps(\n state[\"manifest\"][\"argv\"],\n separators=(\",\", \":\"),\n ensure_ascii=False,\n )"},{"call":"json.dumps","keywords":["ensure_ascii","indent","sort_keys"],"line":1778,"segment_sha256":"d31eb8080be3fc4f69b562e41f97dd655755ae2cdf26f99434c4521f86b0547c","text":"json.dumps(\n capsule_summary,\n ensure_ascii=False,\n indent=2,\n sort_keys=True,\n )"},{"call":"json.dumps","keywords":["ensure_ascii","indent","sort_keys"],"line":1822,"segment_sha256":"e8af89f3e8da544b76204b745215223c8d2381300b60dc0c5e1baf6a4096ffdd","text":"json.dumps(\n meta,\n ensure_ascii=False,\n indent=2,\n sort_keys=True,\n )"}],"schema_fields":["argv","content_b64","mode","payload","risk"],"sha256":"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d"},{"anchors":[{"line":596,"segment_sha256":"bea803e2bf945e9c5008a239e11936ecdbd8475018029010553aae5d638af370","text":"path == \"/bridge/bridge.cmd\""},{"line":791,"segment_sha256":"528504d107f4e3a9c88fb94943e594ed199c19d14b7398d0499ed62a41c176f9","text":"path == \"/api/import\""}],"basename":"homelab-command-portal","bytes":39936,"functions":[{"args":["request"],"end":91,"header":"def adapter_call(request: dict[str, Any]) -> dict[str, Any]:\n encoded = (","hotspot":[{"end":46,"original_sha256":"0810613963b5a41789eb5ecf131bf80b45e647dded9b35c5e68d4b9292f8a223","start":43,"text":"43:\n44:def adapter_call(request: dict[str, Any]) -> dict[str, Any]:\n45: encoded = (\n46: json.dumps("}],"keyword_line_count":7,"name":"adapter_call","segment_sha256":"1d4f3585656373b842054a15f1b11fb43cf9feab695b82df3ea8f5e8a693030a","start":44},{"args":["self","status","content_type","body"],"end":504,"header":" def reply(\n self,","hotspot":[{"end":477,"original_sha256":"aaa0d62cf14511be6509347c1614c7f23cfcf9714885cb1464f9fb9d8961005b","start":474,"text":"474: content_type: str,\n475: body: bytes,\n476: *,\n477: headers: dict[str, str] | None = None,"}],"keyword_line_count":4,"name":"reply","segment_sha256":"0be03d4b20f918f84107b98285a7d9bc750fcb4c717453a041a46ad7271bec53","start":471},{"args":["self"],"end":764,"header":" def do_GET(self) -> None:\n try:","hotspot":[{"end":688,"original_sha256":"dfa2bbf4800083be58a8dfb63301a47bcc206c21d4d158922ec232412fa4a17c","start":685,"text":"685: f\"/r/{short_id}\",\n686: headers={\"Set-Cookie\": cookie},\n687: )\n688: return"}],"keyword_line_count":15,"name":"do_GET","segment_sha256":"e49c3c1e64918367b3f4c1d7404beed09ac2fe19b3be22c59b59e3f8c2d52881","start":553},{"args":["self"],"end":907,"header":" def do_POST(self) -> None:\n try:","hotspot":[{"end":774,"original_sha256":"9d3ee7b22c1c1a4de2f9220e8211c79b320c1f378da508e9408877a6ca0349d5","start":771,"text":"771: if path == \"/api/enroll\":\n772: body = self.read_body(512).decode(\n773: \"ascii\",\n774: errors=\"strict\","}],"keyword_line_count":14,"name":"do_POST","segment_sha256":"6c3b664bc61fb4bc506662a1711d99017254441864528c27da5db76254864694","start":766},{"args":["request"],"end":1045,"header":" def fake_adapter_call(request: dict[str, Any]) -> dict[str, Any]:\n attempts[\"count\"] += 1","hotspot":[{"end":1043,"original_sha256":"cfdde978ab18d008414db8e692c50d3de47ac561eadbc2d7deb81a5a1b17f669","start":1040,"text":"1040:\n1041: def fake_adapter_call(request: dict[str, Any]) -> dict[str, Any]:\n1042: attempts[\"count\"] += 1\n1043: if attempts[\"count\"] < 3:"}],"keyword_line_count":1,"name":"fake_adapter_call","segment_sha256":"ce0cd75c856eb06926ff96b1c3d65c0ef72b6f409b5831122724d22a951fef97","start":1041}],"mode":"0o755","process_sites":[{"call":"json.dumps","keywords":["separators","sort_keys"],"line":46,"segment_sha256":"d2796347998c58685d8dfd45d5df5fe51509645aba7a264e7dc25cb1f352c982","text":"json.dumps(\n request,\n separators=(\",\", \":\"),\n sort_keys=True,\n )"},{"call":"json.loads","keywords":[],"line":81,"segment_sha256":"6a36fbe7611c83cf1f9a144d11feb88410bbc002bb2aeeffc19cd9b97fdab2b4","text":"json.loads(raw)"},{"call":"json.dumps","keywords":["separators","sort_keys"],"line":113,"segment_sha256":"e2fb745bae0108aba634dcdc658da4a7423b1439f0ea5f9c725fb8338e962574","text":"json.dumps(\n result,\n separators=(\",\", \":\"),\n sort_keys=True,\n )"},{"call":"json.dumps","keywords":["ensure_ascii","indent"],"line":337,"segment_sha256":"d6f51399c0a5250e2e7ce94f7692c5d23b32e73e2a40cfe39dfe708615296a95","text":"json.dumps(\n {\n \"status\": status,\n \"execution\": execution,\n \"evidence\": evidence,\n },\n ensure_ascii=False,\n indent=2,\n )"},{"call":"self.rfile.read","keywords":[],"line":541,"segment_sha256":"e88ccc84bddb9730bf85279cc75080f708954fea1522420d79deeef7f4d4022e","text":"self.rfile.read(length)"},{"call":"json.dumps","keywords":["ensure_ascii","separators","sort_keys"],"line":569,"segment_sha256":"54d09d0aed4fa5af8f08233988dff5e409332754d7767eef48c0e09cad7482d3","text":"json.dumps(\n {\n \"status\": \"ok\",\n \"version\": 3,\n \"adapter\": result[\"status\"],\n \"result_sequence\": recent[\n "},{"call":"json.dumps","keywords":["ensure_ascii","separators","sort_keys"],"line":745,"segment_sha256":"c69d1ae04da0c2a85f4db115bb6aca05e6712ea223bec16c952e99dcc0df4f64","text":"json.dumps(\n state,\n ensure_ascii=False,\n separators=(\",\", \":\"),\n sort_keys=True,\n )"}],"schema_fields":["Authorization","Cookie","risk"],"sha256":"97c69bd4fccf7272dadc911281c1503f411bae2dc11dac4b22b87f33d678ae52"}],"analysis_ready":true,"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-HANDOFF-PATCH-CONTEXT-READ-ONLY-V2-20260805T131200Z","command_rc":0,"mutation_outcome":"NO_MUTATION","next_action":"BUILD_SHA_GUARDED_EPHEMERAL_SECRET_HANDOFF_TRANSACTION","output_truncated_in_json":false,"projection":{"degraded":false,"safe_limit_bytes":18000,"strategy":"one_hotspot_per_target_function"},"rc":0,"read_only":true,"required_functions":{"adapter":["run_command","sanitize_state","substitute_argv"],"portal":["adapter_call","do_POST"]},"rollback_restored":null,"rollback_started":false,"root_cause_classification":"SHA_GUARDED_COMPACT_PATCH_CONTEXT_CAPTURED","schema":1,"status":"OK","transaction_requirements":{"atomic_replace":true,"automatic_exact_rollback":true,"byte_for_byte_backup":true,"candidate_compile_and_selftest":true,"candidate_in_temporary_directory":true,"expected_sha_preconditions":{"homelab-command-adapter":"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d","homelab-command-portal":"97c69bd4fccf7272dadc911281c1503f411bae2dc11dac4b22b87f33d678ae52"},"read_exact_current_sources":true,"secret_never_in_capsule_argv_output_or_evidence":true,"service_health_verification":true},"units":[{"active_state":"active","exec_basename":"homelab-command-adapter","exec_path_sha256":"c2e3b43f1f858c6fa265dc276d6a6a29e0cd25e4a127fbc093b8c8d9512bb739","fragment_path_sha256":"afe4d91c280ac4e6e9999498b5f5d8b8842a1f33e30fd45d984879a6392bc045","sub_state":"running","unit":"homelab-command-adapter.service"},{"active_state":"active","exec_basename":"homelab-command-portal","exec_path_sha256":"1132c3c355ed18cdc6406935cd26a128df298f71df7f48df690c72b202ddd7be","fragment_path_sha256":"adf87b0f1c821b17e3e2ff19cc024d783b55caf69460d01fa66f7d2579a71f5a","sub_state":"running","unit":"homelab-command-portal.service"}]} +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z","command_rc":0,"mutation_outcome":"NO_MUTATION","output_truncated_in_json":false,"rc":0,"rollback_restored":null,"rollback_started":false,"status":"OK","version":1} +{"adapter":{"basename":"homelab-command-adapter","mode_risk_contract":{"candidate_values":["HIGH","READ_ONLY","REVERSIBLE","available","change","change capsule must declare production change","change capsule requires available rollback","change capsule risk must be REVERSIBLE or HIGH","invalid mode","invalid risk","non-change capsule cannot declare changes","non-change capsule risk must be READ_ONLY","production"],"comparisons":[{"line":370,"names":["mode"],"segment_sha256":"fb9813b54c11137bed7aedcae743fc0a0db019a66562c6f3380fce1a69f76370","text":"if mode not in ALLOWED_MODES:\n raise AdapterError(\"invalid mode\")","values":["invalid mode"]},{"line":384,"names":["risk"],"segment_sha256":"e49cc412f4f63f1515bfc021820cb8d7f9640f950ea9b8a0f13dad14a60d5839","text":"if risk not in ALLOWED_RISKS:\n raise AdapterError(\"invalid risk\")","values":["invalid risk"]},{"line":386,"names":["mode","risk"],"segment_sha256":"bb56e08695ce4980c221165b414b27f3afc246b8b5c1d3402c1c831292acef5a","text":"if mode == \"change\" and risk not in {\"REVERSIBLE\", \"HIGH\"}:\n raise AdapterError(\"change capsule risk must be REVERSIBLE or HIGH\")","values":["HIGH","REVERSIBLE","change","change capsule risk must be REVERSIBLE or HIGH"]},{"line":386,"names":["mode","risk"],"segment_sha256":"1c673162449940fc60421bc5517f24f7a30580c824b6dfb0de885cd7b98650cb","text":"mode == \"change\" and risk not in {\"REVERSIBLE\", \"HIGH\"}","values":["HIGH","REVERSIBLE","change"]},{"line":386,"names":["mode"],"segment_sha256":"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69","text":"mode == \"change\"","values":["change"]},{"line":386,"names":["risk"],"segment_sha256":"724ee6c7d954e249f31d377b059766cc67b75131513b547c93479821daff1665","text":"risk not in {\"REVERSIBLE\", \"HIGH\"}","values":["HIGH","REVERSIBLE"]},{"line":388,"names":["mode","risk"],"segment_sha256":"c7c3a84d312747700b4f14f46c2d4b5031e7cbcd8cf567c736a690d6d377ce84","text":"if mode != \"change\" and risk != \"READ_ONLY\":\n raise AdapterError(\"non-change capsule risk must be READ_ONLY\")","values":["READ_ONLY","change","non-change capsule risk must be READ_ONLY"]},{"line":388,"names":["mode","risk"],"segment_sha256":"434a09e2c0c02c095361b91cc1e32ab1bb1ffe4dae45c65b541d010268040e03","text":"mode != \"change\" and risk != \"READ_ONLY\"","values":["READ_ONLY","change"]},{"line":388,"names":["mode"],"segment_sha256":"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce","text":"mode != \"change\"","values":["change"]},{"line":388,"names":["risk"],"segment_sha256":"79f7afe950f69ed28d3f9245007eb96ade840ed1e6b3dbe1b06c2ff5d55038e1","text":"risk != \"READ_ONLY\"","values":["READ_ONLY"]},{"line":399,"names":["mode"],"segment_sha256":"d640c7dc4427bd639bf28465290f4701b93d1fddd4adee8a03f1d80ce32eb387","text":"if mode != \"change\" and any(flags.values()):\n raise AdapterError(\n \"non-change capsule cannot declare changes\"\n )","values":["change","non-change capsule cannot declare changes"]},{"line":399,"names":["mode"],"segment_sha256":"266d98ea980186e8471babd7f4c560a932d94a83be926a459beaed430da7dc84","text":"mode != \"change\" and any(flags.values())","values":["change"]},{"line":399,"names":["mode"],"segment_sha256":"b11dada48a10d3dd45c37ed5841dfd90fe39169d56a8d87bb3db50de138540ce","text":"mode != \"change\"","values":["change"]},{"line":403,"names":["mode"],"segment_sha256":"c24b94f6049271719b2ea5316cfc4d72d3cef3c615462c5648b24974163c497a","text":"if mode == \"change\" and not flags[\"production\"]:\n raise AdapterError(\n \"change capsule must declare production change\"\n )","values":["change","change capsule must declare production change","production"]},{"line":403,"names":["mode"],"segment_sha256":"f0c2605aac2630fd54fda61abe05546ff3d3d977c4a6a50125e020869a49301a","text":"mode == \"change\" and not flags[\"production\"]","values":["change","production"]},{"line":403,"names":["mode"],"segment_sha256":"8917390eaf3d01fb76a51dfd8243748ec4bd46c94d93ae4d47382246b8e52a69","text":"mode == \"change\"","values":["change"]}],"raises":[{"line":371,"segment_sha256":"6d78e0909f5bb1c43cef5c9bc042720485fd0fbcb2762ccf45b7ecae433a904b","text":"raise AdapterError(\"invalid mode\")"},{"line":385,"segment_sha256":"87216e6143dce952e5941a434e807e0a5ed4f39b1e04aca99176a8aa6453e1ad","text":"raise AdapterError(\"invalid risk\")"},{"line":387,"segment_sha256":"43098cc02c674830f07b2d9438e5a31307585cf955039af501a23b8f05600037","text":"raise AdapterError(\"change capsule risk must be REVERSIBLE or HIGH\")"},{"line":389,"segment_sha256":"a00c40ee846c32cb3b5198553cb60d4967d4ea2b06f65174fd436ca696009f82","text":"raise AdapterError(\"non-change capsule risk must be READ_ONLY\")"},{"line":542,"segment_sha256":"e4509eefed0a60ced14742d43e40dd528988c46b11c81a162eaf1b97b5c4969c","text":"raise AdapterError(\"invalid payload mode\")"}]},"process_sites":[{"call":"subprocess.run","line":664,"names":[],"segment_sha256":"fbe36f5d1ed7b23d545f105135de2993138aa4a8dafc9f5419d7c37b36deebae","stderr":"subprocess.PIPE","stdin":"subprocess.DEVNULL","stdout":"subprocess.PIPE","text":"subprocess.run(\n args,\n stdin=subprocess.DEVNULL,\n stdout=subprocess.PIPE,\n stderr=subprocess.PIPE,\n text=True,\n check=False,\n timeout=timeout,\n env=(SAFE_ENV if env is None else env),\n )"},{"call":"subprocess.Popen","line":1626,"names":[],"segment_sha256":"90bb736720d2877f6704459828dc5551619ba00834a4660e9ed9c7f86e05b8c6","stderr":"subprocess.STDOUT","stdin":"subprocess.DEVNULL","stdout":"handle","text":"subprocess.Popen(\n [\n sys.executable,\n \"-B\",\n str(Path(__file__).resolve()),\n \"--worker\",\n short_id,\n ],\n stdin=subprocess.DEVNULL,\n stdout=handle,\n stderr=subprocess.STDOUT,\n env=SAFE_ENV,\n start_new_session=True,\n close_fds=True,\n )"},{"call":"subprocess.Popen","line":2056,"names":[],"segment_sha256":"4582da2d6b8e31108deedee5a5d6b877788db5da0f6d52120a605d76d0037d97","stderr":"subprocess.STDOUT","stdin":"subprocess.DEVNULL","stdout":"subprocess.PIPE","text":"subprocess.Popen(\n args,\n stdin=subprocess.DEVNULL,\n stdout=subprocess.PIPE,\n stderr=subprocess.STDOUT,\n text=True,\n env=environment,\n start_new_session=True,\n close_fds=True,\n )"}],"sha256":"a1a7a615c99568bf915d084cc476f0ebf54ab0eedf3ecd578c4b0e072f58c43d"},"analysis_ready":true,"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-HANDOFF-MUTATION-CONTRACT-READ-ONLY-20260805T132500Z","command_rc":0,"mutation_outcome":"NO_MUTATION","next_action":"BUILD_SHA_GUARDED_SECRET_HANDOFF_TRANSACTION","output_truncated_in_json":false,"rc":0,"read_only":true,"required_transaction_guards":{"atomic_replace":true,"automatic_exact_rollback":true,"byte_for_byte_backup":true,"candidate_compile_and_selftest":true,"candidate_in_temporary_directory":true,"expected_sha_preconditions":true,"read_exact_current_sources":true,"secret_never_in_capsule_argv_output_or_evidence":true,"service_health_verification":true},"rollback_restored":null,"rollback_started":false,"root_cause_classification":"MUTATION_CAPSULE_AND_STDIN_CONTRACT_CAPTURED","runner_candidates":[],"schema":1,"status":"OK"} OUTPUT_END CHAT_OUTPUT_END