diff --git a/runtime/history/HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z.json b/runtime/history/HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z.json new file mode 100644 index 0000000..86166eb --- /dev/null +++ b/runtime/history/HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z", + "status": "FAIL", + "rc": 1, + "host": "pve01", + "mode": "verify", + "component": "homelab-cluster-admin-update-visibility", + "started_at_utc": "2026-08-05T10:50:15Z", + "finished_at_utc": "2026-08-05T10:50:15Z", + "reference_register_checked": true, + "reference_sha256": "5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e", + "error_register_checked": true, + "error_register_sha256": "24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83", + "command_sha256": "a7878de372fb306cc0a189b94b9719cd8d78f33c2db2afa22ddcb3ab93bda156", + "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": 1, + "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": "06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32", + "sanitized_output_sha256": "06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32", + "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-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z\",\"command_rc\":1,\"control_plane_error\":null,\"mutation_outcome\":\"NO_MUTATION\",\"rc\":1,\"rollback_restored\":false,\"rollback_started\":false,\"status\":\"FAIL\",\"version\":1}\n{\"changes_made\":false,\"command_id\":\"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z\",\"error\":\"V6 output cardinality contracts=1 reports=0\",\"error_type\":\"RuntimeError\",\"mutation_outcome\":\"NO_MUTATION\",\"read_only\":true,\"rollback_restored\":false,\"rollback_started\":false,\"schema\":7,\"status\":\"FAIL\"}\n" +} diff --git a/runtime/history/HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z.txt b/runtime/history/HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z.txt new file mode 100644 index 0000000..17ae77e --- /dev/null +++ b/runtime/history/HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z.txt @@ -0,0 +1,34 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z +STATUS=FAIL +RC=1 +HOST=pve01 +MODE=verify +COMPONENT=homelab-cluster-admin-update-visibility +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83 +COMMAND_SHA256=a7878de372fb306cc0a189b94b9719cd8d78f33c2db2afa22ddcb3ab93bda156 +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=1 +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=06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32 +SANITIZED_OUTPUT_SHA256=06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32 +OUTPUT_BEGIN +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z","command_rc":1,"control_plane_error":null,"mutation_outcome":"NO_MUTATION","rc":1,"rollback_restored":false,"rollback_started":false,"status":"FAIL","version":1} +{"changes_made":false,"command_id":"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z","error":"V6 output cardinality contracts=1 reports=0","error_type":"RuntimeError","mutation_outcome":"NO_MUTATION","read_only":true,"rollback_restored":false,"rollback_started":false,"schema":7,"status":"FAIL"} + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index 73357c0..86166eb 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "HOMELAB-SKLADCHIK-EDGE-EXECUTION-PATH-READ-ONLY-20260805T103400Z", - "status": "OK", - "rc": 0, + "command_id": "HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z", + "status": "FAIL", + "rc": 1, "host": "pve01", "mode": "verify", - "component": "skladchik-edge-execution-path-read-only", - "started_at_utc": "2026-08-05T10:36:16Z", - "finished_at_utc": "2026-08-05T10:36:16Z", + "component": "homelab-cluster-admin-update-visibility", + "started_at_utc": "2026-08-05T10:50:15Z", + "finished_at_utc": "2026-08-05T10:50:15Z", "reference_register_checked": true, "reference_sha256": "5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e", "error_register_checked": true, "error_register_sha256": "24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83", - "command_sha256": "ac7e1774fc12c145877214a3ff3d2807e18b02d6b0f1d4af3fe9d28c94551b41", + "command_sha256": "a7878de372fb306cc0a189b94b9719cd8d78f33c2db2afa22ddcb3ab93bda156", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -21,7 +21,7 @@ "result_contract_valid": true, "result_contract_status": null, "result_contract_error": null, - "command_rc": 0, + "command_rc": 1, "changes_made": false, "rollback_started": false, "rollback_restored": null, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "cd2627d141bd73e6985c73fd88f92b2de9061163e1647c068781cff882f50355", - "sanitized_output_sha256": "7b13465d38bf723d42fce218d2178e7f914e0d6b84828047df9d8537874c31c2", + "raw_evidence_sha256": "06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32", + "sanitized_output_sha256": "06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32", "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-EDGE-EXECUTION-PATH-READ-ONLY-20260805T103400Z\",\"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{\"analysis_ready\":false,\"based_on\":{\"capsule_sha256\":\"993b0db88e76693fb64003850f970a1ccfd86ee655c6649ae402c4e23fea367f\",\"command_id\":\"HOMELAB-SKLADCHIK-RUNTIME-EXACT-SUMMARY-READ-ONLY-20260805T102600Z\",\"output_sha256\":\"f19a8cf0f70a091ebc7f9956c9c8e5df934d2fd7369dde5d47afd2241fba9450\",\"runner_json_sha256\":\"374c78d71eecf32b191f62a435d83ce83840ffbcb0d2a7ae6a217505940be85b\",\"runner_text_sha256\":\"241b283ab935391764553f6be92d6403fa60dbece2d583cb57107698474a5e53\"},\"changes_made\":false,\"command_id\":\"HOMELAB-SKLADCHIK-EDGE-EXECUTION-PATH-READ-ONLY-20260805T103400Z\",\"command_rc\":0,\"mutation_outcome\":\"NO_MUTATION\",\"next_action\":\"RESOLVE_EDGE_SSH_TEMPLATE_FROM_VERIFIED_SOURCE\",\"ops_assets\":[{\"bytes\":1340,\"excerpts\":[{\"line\":4,\"text\":\"\\\"branch\\\": \\\"cr-2026-0007-skladchik-controlled-reauth\\\",\"},{\"line\":6,\"text\":\"\\\"scope\\\": \\\"controlled Skladchik monitor reauthentication with strict known_hosts\\\",\"},{\"line\":9,\"text\":\"\\\"task_id\\\": \\\"skladchik-reports-monitor-controlled-reauth-v1\\\",\"},{\"line\":10,\"text\":\"\\\"edge_script_sha256\\\": \\\"b13d846cf089d450e3d5ac9e85ad1e232c198930e466bb8b82f6983a4d48ce0e\\\",\"},{\"line\":23,\"text\":\"\\\"active_skladchik_sources_versioned\\\": 5,\"},{\"line\":24,\"text\":\"\\\"edge_mutation_script_versioned\\\": true,\"},{\"line\":26,\"text\":\"\\\"REG-024-SKLADCHIK-REAUTH-STRICT-HOSTKEY\\\",\"},{\"line\":28,\"text\":\"\\\"REG-026-ACTIVE-SKLADCHIK-STRICT-HOSTKEY-COVERAGE\\\",\"},{\"line\":29,\"text\":\"\\\"REG-027-REMOTE-MUTATION-SCRIPT-MUST-BE-VERSIONED\\\",\"}],\"path\":\"changes/CR-2026-0007/plan.json\",\"present\":true,\"sha256\":\"9a1cd77ebb9a880869aa24711408a88abadddd3ac4e43b04510e8ac13ba545c2\"},{\"bytes\":3498,\"excerpts\":[{\"line\":1,\"text\":\"31ddb9088f30e892690e3dd7fe184b8da113d473dd4744fc7d78857d9b43b272 tasks/skladchik-reports-monitor-controlled-reauth-v1/README.txt\"},{\"line\":2,\"text\":\"b13d846cf089d450e3d5ac9e85ad1e232c198930e466bb8b82f6983a4d48ce0e tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge/skladchik-reports-monitor-cookie-update-edge\"},{\"line\":3,\"text\":\"971b63baa5c9d9e0391e9adf8c289406e8da408a1aeb32e089740272eb280bd9 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-dry-run.sh\"},{\"line\":4,\"text\":\"bc46788a8f7dbe50b7ef600727f72b76981a23fdfc026cd10ba857fad9edb0e1 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-preflight.sh\"},{\"line\":5,\"text\":\"542c2dfcefcf9f41661887fdbd4cff6c827c69407dad478914c521dfcf106549 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-prepare.sh\"},{\"line\":6,\"text\":\"ea79bd668bdc1854b45316df88b9314b9551ee4e02da506f513031530b7270ed tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-rollback.sh\"},{\"line\":7,\"text\":\"a34c01cc60c95f256471079f1b47330077c86f2a87d716c30bfaa6b0f58dabb3 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-seal.sh\"},{\"line\":8,\"text\":\"12db8e75a128398dd8de6fd8e3db0db45063ebfdc174c2e38e5d27753e3ca68e tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-verify.sh\"},{\"line\":9,\"text\":\"cf1740c5a7af0037a2de8b5c33dc83001dc7cca3dcb3f348669aa7f96a2d1131 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/__pycache__/skladchik-reports-monitor-monthly-selftest-watchcpython-313.pyc\"},{\"line\":10,\"text\":\"5c689841c8a46ba1a4679dcfa2b7bc9ab8ccfc9fdf8d3f7a3f90cf0c3df521b9 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/__pycache__/skladchik-reports-monitor-supervisorcpython-313.pyc\"},{\"line\":11,\"text\":\"1912f8f0559637563972bb8ac984fb0036694092056ae53968c02cc3b67855f3 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/skladchik-reports-monitor-backup\"},{\"line\":12,\"text\":\"ea2d89ce67893a6d89b29610e4d46e207932ecc157173454585f67890f58810c tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/skladchik-reports-monitor-cookie-update\"}],\"path\":\"changes/CR-2026-0007/task-package.sha256\",\"present\":true,\"sha256\":\"40515974b5cb0acac0e1d4c1b6f1eea95f71a9df093304e65c1c66cc9b820356\"},{\"bytes\":3020,\"excerpts\":[{\"line\":1,\"text\":\"# Ежемесячное обновление Cookie для Skladchik\"},{\"line\":8,\"text\":\"/srv/homelab-ops/tools/skladchik-cookie-refresh\"},{\"line\":15,\"text\":\"Он не отключает защиту от параллельного backup/restore. Перед каждой фазой сценарий ждёт три последовательные чистые проверки. При ошибке до `seal` запускается проверенный rollback, который восстанавливает прежние Cookie, cookie jar, скрипты, desired-state, таймер и состояние supervisor.\"},{\"line\":17,\"text\":\"## Где взять Cookie\"},{\"line\":19,\"text\":\"1. Откройте `https://az52.skladchik.org/reports/` в уже авторизованном браузере.\"},{\"line\":22,\"text\":\"4. Выберите запрос к `/reports/`.\"},{\"line\":23,\"text\":\"5. В **Request Headers** найдите заголовок `Cookie`.\"},{\"line\":24,\"text\":\"6. Копируйте только его значение, без текста `Cookie=\"},{\"line\":30,\"text\":\"Первый запуск принудительно удаляет старый persistent jar и использует только новый браузерный Cookie. Второй запуск временно исключает браузерный Cookie из secrets и обязан успешно пройти только с новым jar. Это доказывает, что дальнейшая работа таймера не зависит от интерактивного ввода.\"},{\"line\":35,\"text\":\"COOKIE_REFRESH_RESULT=SUCCESS\"},{\"line\":36,\"text\":\"FRESH_COOKIE_FORCED=YES\"},{\"line\":37,\"text\":\"STALE_COOKIE_JAR_BYPASSED=YES\"}],\"path\":\"docs/skladchik-cookie-refresh.md\",\"present\":true,\"sha256\":\"91c66d8ee6622d925174055599ad5ece6270c35f8d7d7967a26609f7e290c7e6\"},{\"bytes\":770,\"excerpts\":[{\"line\":1,\"text\":\"Controlled one-time Skladchik monitor reauthentication.\"},{\"line\":4,\"text\":\"legacy host-key auto-acceptance. It pins the exact edge update script hash,\"},{\"line\":5,\"text\":\"creates a root-only rollback snapshot on edge, opens the existing hidden\"},{\"line\":6,\"text\":\"interactive prompt through strict known_hosts SSH, verifies monitor counts and\"},{\"line\":7,\"text\":\"persistent cookie health, clears only the Skladchik supervisor failed latch,\"},{\"line\":10,\"text\":\"Cookie content is never stored in Git, task output, or command arguments.\"},{\"line\":12,\"text\":\"MONTHLY COOKIE REFRESH ENTRYPOINT\"},{\"line\":14,\"text\":\"/srv/homelab-ops/tools/skladchik-cookie-refresh\"},{\"line\":15,\"text\":\"Runbook: docs/skladchik-cookie-refresh.md\"},{\"line\":16,\"text\":\"Never place Cookie values in Git, chat, shell history, or logs.\"}],\"path\":\"tasks/skladchik-reports-monitor-controlled-reauth-v1/README.txt\",\"present\":true,\"sha256\":\"7e2e699c9e4a3418a6fc357585be6e3d911480071a6dd653b2ea908163da1eb4\"},{\"bytes\":890,\"excerpts\":[{\"line\":1,\"text\":\"#!/usr/bin/env bash\"},{\"line\":5,\"text\":\"TASK_ID=skladchik-reports-monitor-controlled-reauth-v1\"},{\"line\":6,\"text\":\"case \\\"$STAGE\\\" in /var/lib/homelab-admin/rollback/\\\"$TASK_ID\\\") ;; *) exit 64 ;; esac\"},{\"line\":9,\"text\":\"test -s \\\"$STAGE/health.txt\\\"\"},{\"line\":17,\"text\":\"test \\\"$(sha256sum /usr/local/sbin/skladchik-reports-monitor-cookie-update-edge | awk '{print $1}')\\\" = \\\"$EXPECTED_SHA\\\"\"}],\"path\":\"tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-dry-run.sh\",\"present\":true,\"sha256\":\"ca42f68133086af7afd78a6d65e54a905a0ac9cfe583b867a98cd121addf732f\"}],\"output_truncated_in_json\":false,\"prerequisites\":{\"repo\":{\"head\":\"60f53ea6fe6724196802a46de3de19c7889a51cc\",\"path\":\"/srv/homelab-ops-worktrees/cr-2026-0015\",\"symbolic_head\":\"refs/heads/cr-2026-0015-pve03-r8152-rx-ring-canary\",\"verified\":true},\"supervisor_path\":\"/usr/local/sbin/skladchik-reports-monitor-supervisor\",\"supervisor_sha256\":\"bd40ee19ea8b277d52f4240b97d3c79b825c90154272bac8a43004591bd0ddc3\",\"supervisor_sha_verified\":true,\"unit_path\":\"/etc/systemd/system/skladchik-reports-monitor-supervisor.service\",\"unit_sha256\":\"e874fb03573b76181f3eb812c7285848e60705923c172a2f102504a7b9100ef7\",\"unit_sha_verified\":true},\"projection_bytes\":14930,\"rc\":0,\"read_only\":true,\"rollback_restored\":null,\"rollback_started\":false,\"root_cause_classification\":\"EDGE_EXECUTION_PATH_INCOMPLETE\",\"schema\":1,\"ssh_metadata\":{\"artifacts\":[{\"bytes\":117,\"is_symlink\":false,\"mode\":\"0o640\",\"path\":\"[SENSITIVE_PATH] / \\\"health.txt\\\"\"}},{\"line\":16,\"name\":\"STATE\",\"value\":{\"expression\":\"STATE_DIR / \\\"state.env\\\"\"}},{\"line\":17,\"name\":\"LOG\",\"value\":{\"expression\":\"LOG_DIR / \\\"supervisor.log\\\"\"}},{\"line\":19,\"name\":\"MONITOR_HEALTH_AGE_MAX\",\"value\":{\"expression\":\"int(os.environ.get(\\\"SKLADCHIK_MONITOR_HEALTH_MAX_SECONDS\\\", \\\"600\\\"))\"}},{\"line\":20,\"name\":\"BACKUP_HEALTH_AGE_MAX\",\"value\":{\"expression\":\"int(os.environ.get(\\\"SKLADCHIK_BACKUP_HEALTH_MAX_SECONDS\\\", \\\"129600\\\"))\"}},{\"line\":21,\"name\":\"RESTORE_HEALTH_AGE_MAX\",\"value\":{\"expression\":\"int(os.environ.get(\\\"SKLADCHIK_RESTORE_HEALTH_MAX_SECONDS\\\", \\\"691200\\\"))\"}},{\"line\":22,\"name\":\"COOKIE_EXPIRY_WARN_SECONDS\",\"value\":{\"expression\":\"int(os.environ.get(\\\"SKLADCHIK_COOKIE_EXPIRY_WARN_SECONDS\\\", \\\"604800\\\"))\"}},{\"line\":24,\"name\":\"PVE_BACKUP_HEALTH\",\"value\":\"/var/lib/skladchik-reports-monitor-backup/health.txt\"},{\"line\":25,\"name\":\"PVE_RESTORE_HEALTH\",\"value\":\"/var/lib/skladchik-reports-monitor-backup/restore-check-health.txt\"}],\"ast_parsed\":true,\"edge_assignment_present\":true,\"execution_excerpts\":[{\"line\":12,\"text\":\"EDGE = os.environ.get(\\\"SKLADCHIK_EDGE\\\", \\\"debian@\\\")\"},{\"line\":13,\"text\":\"STATE_DIR = Path(\\\"/var/lib/skladchik-reports-monitor-supervisor\\\")\"},{\"line\":14,\"text\":\"LOG_DIR = Path(\\\"/var/log/skladchik-reports-monitor-supervisor\\\")\"},{\"line\":15,\"text\":\"HEALTH = STATE_DIR / \\\"health.txt\\\"\"},{\"line\":19,\"text\":\"MONITOR_HEALTH_AGE_MAX = int(os.environ.get(\\\"SKLADCHIK_MONITOR_HEALTH_MAX_SECONDS\\\", \\\"600\\\"))\"},{\"line\":20,\"text\":\"BACKUP_HEALTH_AGE_MAX = int(os.environ.get(\\\"SKLADCHIK_BACKUP_HEALTH_MAX_SECONDS\\\", \\\"129600\\\"))\"},{\"line\":21,\"text\":\"RESTORE_HEALTH_AGE_MAX = int(os.environ.get(\\\"SKLADCHIK_RESTORE_HEALTH_MAX_SECONDS\\\", \\\"691200\\\"))\"},{\"line\":22,\"text\":\"COOKIE_EXPIRY_WARN_SECONDS = int(os.environ.get(\\\"SKLADCHIK_COOKIE_EXPIRY_WARN_SECONDS\\\", \\\"604800\\\"))\"},{\"line\":24,\"text\":\"PVE_BACKUP_HEALTH = Path(\\\"/var/lib/skladchik-reports-monitor-backup/health.txt\\\")\"},{\"line\":25,\"text\":\"PVE_RESTORE_HEALTH = Path(\\\"/var/lib/skladchik-reports-monitor-backup/restore-check-health.txt\\\")\"},{\"line\":73,\"text\":\"def ssh_edge(cmd, timeout=45):\"},{\"line\":74,\"text\":\"q = \\\"ssh -o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=[SENSITIVE_PATH] \\\" + shlex.quote(EDGE) + \\\" \\\" + shlex.quote(\\\"sudo bash -lc \\\" + shlex.quote(cmd))\"},{\"line\":77,\"text\":\"def edge_mail(subject, body):\"}],\"functions\":[{\"args\":[\"msg\"],\"contains_cookie\":false,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":33,\"name\":\"log\"},{\"args\":[\"cmd\",\"timeout\"],\"contains_cookie\":false,\"contains_ssh\":true,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":73,\"name\":\"ssh_edge\"},{\"args\":[\"subject\",\"body\"],\"contains_cookie\":false,\"contains_ssh\":true,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":77,\"name\":\"edge_mail\"},{\"args\":[\"units\"],\"contains_cookie\":false,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":true,\"line\":94,\"name\":\"systemctl_props\"},{\"args\":[],\"contains_cookie\":true,\"contains_ssh\":true,\"contains_subprocess\":false,\"contains_systemctl\":true,\"line\":105,\"name\":\"gather\"},{\"args\":[\"status\",\"facts\",\"problems\",\"mode\"],\"contains_cookie\":true,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":284,\"name\":\"render_body\"},{\"args\":[\"status\",\"facts\",\"problems\",\"mail_sent\"],\"contains_cookie\":false,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":334,\"name\":\"write_health\"},{\"args\":[],\"contains_cookie\":false,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":342,\"name\":\"read_state\"},{\"args\":[\"status\",\"problems\"],\"contains_cookie\":false,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":345,\"name\":\"write_state\"},{\"args\":[],\"contains_cookie\":false,\"contains_ssh\":false,\"contains_subprocess\":false,\"contains_systemctl\":false,\"line\":349,\"name\":\"main\"}],\"paths\":[\"/dev/null\",\"/etc/skladchik-reports-monitor/config.ini\",\"/etc/skladchik-reports-monitor/secrets.env\",\"/opt/skladchik-reports-monitor/event-selftest-core\",\"/opt/skladchik-reports-monitor/event-selftest-runner.py\",\"/opt/skladchik-reports-monitor/monitor.py\",\"/opt/skladchik-reports-monitor/operational_digest.py\",\"[SENSITIVE_PATH] = os.environ.get(\\\"SKLADCHIK_EDGE\\\", \\\"debian@\\\")\"},{\"line\":73,\"text\":\"def ssh_edge(cmd, timeout=45):\"},{\"line\":74,\"text\":\"q = \\\"ssh -o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=[SENSITIVE_PATH] \\\" + shlex.quote(EDGE) + \\\" \\\" + shlex.quote(\\\"sudo bash -lc \\\" + shlex.quote(cmd))\"},{\"line\":77,\"text\":\"def edge_mail(subject, body):\"},{\"line\":90,\"text\":\"rc, out = ssh_edge(\\\"python3 -c \\\" + shlex.quote(py), timeout=60)\"},{\"line\":109,\"text\":\"edge_cmd = r'''\"},{\"line\":149,\"text\":\"rc, out = ssh_edge(edge_cmd, timeout=45)\"},{\"line\":150,\"text\":\"facts[\\\"edge_ssh_rc\\\"] = str(rc)\"},{\"line\":152,\"text\":\"problems.append(\\\"edge_ssh_failed\\\")\"}],\"ssh_function_present\":true,\"top_level_import_safe\":true,\"units\":[\"skladchik-reports-monitor-age-alert.timer\",\"skladchik-reports-monitor-event-selftest.timer\",\"skladchik-reports-monitor-heartbeat.timer\",\"skladchik-reports-monitor-watchdog.timer\",\"skladchik-reports-monitor-weekly-summary.timer\",\"skladchik-reports-monitor.timer\"]}}\n" + "output": "HOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z\",\"command_rc\":1,\"control_plane_error\":null,\"mutation_outcome\":\"NO_MUTATION\",\"rc\":1,\"rollback_restored\":false,\"rollback_started\":false,\"status\":\"FAIL\",\"version\":1}\n{\"changes_made\":false,\"command_id\":\"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z\",\"error\":\"V6 output cardinality contracts=1 reports=0\",\"error_type\":\"RuntimeError\",\"mutation_outcome\":\"NO_MUTATION\",\"read_only\":true,\"rollback_restored\":false,\"rollback_started\":false,\"schema\":7,\"status\":\"FAIL\"}\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index a8c9824..17ae77e 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,22 +1,22 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=HOMELAB-SKLADCHIK-EDGE-EXECUTION-PATH-READ-ONLY-20260805T103400Z -STATUS=OK -RC=0 +COMMAND_ID=HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z +STATUS=FAIL +RC=1 HOST=pve01 MODE=verify -COMPONENT=skladchik-edge-execution-path-read-only +COMPONENT=homelab-cluster-admin-update-visibility REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=24934a2c7fa5c26f6e828583c4aefac7f143b40c0171736ed7571e617d55ab83 -COMMAND_SHA256=ac7e1774fc12c145877214a3ff3d2807e18b02d6b0f1d4af3fe9d28c94551b41 +COMMAND_SHA256=a7878de372fb306cc0a189b94b9719cd8d78f33c2db2afa22ddcb3ab93bda156 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 +COMMAND_RC=1 CHANGES_MADE=false ROLLBACK_STARTED=false ROLLBACK_RESTORED=null @@ -24,11 +24,11 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=cd2627d141bd73e6985c73fd88f92b2de9061163e1647c068781cff882f50355 -SANITIZED_OUTPUT_SHA256=7b13465d38bf723d42fce218d2178e7f914e0d6b84828047df9d8537874c31c2 +RAW_EVIDENCE_SHA256=06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32 +SANITIZED_OUTPUT_SHA256=06ff6111d6953bf48590b68642873b516612eb9fabd1631148c08d94f32dfa32 OUTPUT_BEGIN -HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-EDGE-EXECUTION-PATH-READ-ONLY-20260805T103400Z","command_rc":0,"mutation_outcome":"NO_MUTATION","output_truncated_in_json":false,"rc":0,"rollback_restored":null,"rollback_started":false,"status":"OK","version":1} -{"analysis_ready":false,"based_on":{"capsule_sha256":"993b0db88e76693fb64003850f970a1ccfd86ee655c6649ae402c4e23fea367f","command_id":"HOMELAB-SKLADCHIK-RUNTIME-EXACT-SUMMARY-READ-ONLY-20260805T102600Z","output_sha256":"f19a8cf0f70a091ebc7f9956c9c8e5df934d2fd7369dde5d47afd2241fba9450","runner_json_sha256":"374c78d71eecf32b191f62a435d83ce83840ffbcb0d2a7ae6a217505940be85b","runner_text_sha256":"241b283ab935391764553f6be92d6403fa60dbece2d583cb57107698474a5e53"},"changes_made":false,"command_id":"HOMELAB-SKLADCHIK-EDGE-EXECUTION-PATH-READ-ONLY-20260805T103400Z","command_rc":0,"mutation_outcome":"NO_MUTATION","next_action":"RESOLVE_EDGE_SSH_TEMPLATE_FROM_VERIFIED_SOURCE","ops_assets":[{"bytes":1340,"excerpts":[{"line":4,"text":"\"branch\": \"cr-2026-0007-skladchik-controlled-reauth\","},{"line":6,"text":"\"scope\": \"controlled Skladchik monitor reauthentication with strict known_hosts\","},{"line":9,"text":"\"task_id\": \"skladchik-reports-monitor-controlled-reauth-v1\","},{"line":10,"text":"\"edge_script_sha256\": \"b13d846cf089d450e3d5ac9e85ad1e232c198930e466bb8b82f6983a4d48ce0e\","},{"line":23,"text":"\"active_skladchik_sources_versioned\": 5,"},{"line":24,"text":"\"edge_mutation_script_versioned\": true,"},{"line":26,"text":"\"REG-024-SKLADCHIK-REAUTH-STRICT-HOSTKEY\","},{"line":28,"text":"\"REG-026-ACTIVE-SKLADCHIK-STRICT-HOSTKEY-COVERAGE\","},{"line":29,"text":"\"REG-027-REMOTE-MUTATION-SCRIPT-MUST-BE-VERSIONED\","}],"path":"changes/CR-2026-0007/plan.json","present":true,"sha256":"9a1cd77ebb9a880869aa24711408a88abadddd3ac4e43b04510e8ac13ba545c2"},{"bytes":3498,"excerpts":[{"line":1,"text":"31ddb9088f30e892690e3dd7fe184b8da113d473dd4744fc7d78857d9b43b272 tasks/skladchik-reports-monitor-controlled-reauth-v1/README.txt"},{"line":2,"text":"b13d846cf089d450e3d5ac9e85ad1e232c198930e466bb8b82f6983a4d48ce0e tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge/skladchik-reports-monitor-cookie-update-edge"},{"line":3,"text":"971b63baa5c9d9e0391e9adf8c289406e8da408a1aeb32e089740272eb280bd9 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-dry-run.sh"},{"line":4,"text":"bc46788a8f7dbe50b7ef600727f72b76981a23fdfc026cd10ba857fad9edb0e1 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-preflight.sh"},{"line":5,"text":"542c2dfcefcf9f41661887fdbd4cff6c827c69407dad478914c521dfcf106549 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-prepare.sh"},{"line":6,"text":"ea79bd668bdc1854b45316df88b9314b9551ee4e02da506f513031530b7270ed tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-rollback.sh"},{"line":7,"text":"a34c01cc60c95f256471079f1b47330077c86f2a87d716c30bfaa6b0f58dabb3 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-seal.sh"},{"line":8,"text":"12db8e75a128398dd8de6fd8e3db0db45063ebfdc174c2e38e5d27753e3ca68e tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-verify.sh"},{"line":9,"text":"cf1740c5a7af0037a2de8b5c33dc83001dc7cca3dcb3f348669aa7f96a2d1131 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/__pycache__/skladchik-reports-monitor-monthly-selftest-watchcpython-313.pyc"},{"line":10,"text":"5c689841c8a46ba1a4679dcfa2b7bc9ab8ccfc9fdf8d3f7a3f90cf0c3df521b9 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/__pycache__/skladchik-reports-monitor-supervisorcpython-313.pyc"},{"line":11,"text":"1912f8f0559637563972bb8ac984fb0036694092056ae53968c02cc3b67855f3 tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/skladchik-reports-monitor-backup"},{"line":12,"text":"ea2d89ce67893a6d89b29610e4d46e207932ecc157173454585f67890f58810c tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/pve01/skladchik-reports-monitor-cookie-update"}],"path":"changes/CR-2026-0007/task-package.sha256","present":true,"sha256":"40515974b5cb0acac0e1d4c1b6f1eea95f71a9df093304e65c1c66cc9b820356"},{"bytes":3020,"excerpts":[{"line":1,"text":"# Ежемесячное обновление Cookie для Skladchik"},{"line":8,"text":"/srv/homelab-ops/tools/skladchik-cookie-refresh"},{"line":15,"text":"Он не отключает защиту от параллельного backup/restore. Перед каждой фазой сценарий ждёт три последовательные чистые проверки. При ошибке до `seal` запускается проверенный rollback, который восстанавливает прежние Cookie, cookie jar, скрипты, desired-state, таймер и состояние supervisor."},{"line":17,"text":"## Где взять Cookie"},{"line":19,"text":"1. Откройте `https://az52.skladchik.org/reports/` в уже авторизованном браузере."},{"line":22,"text":"4. Выберите запрос к `/reports/`."},{"line":23,"text":"5. В **Request Headers** найдите заголовок `Cookie`."},{"line":24,"text":"6. Копируйте только его значение, без текста `Cookie="},{"line":30,"text":"Первый запуск принудительно удаляет старый persistent jar и использует только новый браузерный Cookie. Второй запуск временно исключает браузерный Cookie из secrets и обязан успешно пройти только с новым jar. Это доказывает, что дальнейшая работа таймера не зависит от интерактивного ввода."},{"line":35,"text":"COOKIE_REFRESH_RESULT=SUCCESS"},{"line":36,"text":"FRESH_COOKIE_FORCED=YES"},{"line":37,"text":"STALE_COOKIE_JAR_BYPASSED=YES"}],"path":"docs/skladchik-cookie-refresh.md","present":true,"sha256":"91c66d8ee6622d925174055599ad5ece6270c35f8d7d7967a26609f7e290c7e6"},{"bytes":770,"excerpts":[{"line":1,"text":"Controlled one-time Skladchik monitor reauthentication."},{"line":4,"text":"legacy host-key auto-acceptance. It pins the exact edge update script hash,"},{"line":5,"text":"creates a root-only rollback snapshot on edge, opens the existing hidden"},{"line":6,"text":"interactive prompt through strict known_hosts SSH, verifies monitor counts and"},{"line":7,"text":"persistent cookie health, clears only the Skladchik supervisor failed latch,"},{"line":10,"text":"Cookie content is never stored in Git, task output, or command arguments."},{"line":12,"text":"MONTHLY COOKIE REFRESH ENTRYPOINT"},{"line":14,"text":"/srv/homelab-ops/tools/skladchik-cookie-refresh"},{"line":15,"text":"Runbook: docs/skladchik-cookie-refresh.md"},{"line":16,"text":"Never place Cookie values in Git, chat, shell history, or logs."}],"path":"tasks/skladchik-reports-monitor-controlled-reauth-v1/README.txt","present":true,"sha256":"7e2e699c9e4a3418a6fc357585be6e3d911480071a6dd653b2ea908163da1eb4"},{"bytes":890,"excerpts":[{"line":1,"text":"#!/usr/bin/env bash"},{"line":5,"text":"TASK_ID=skladchik-reports-monitor-controlled-reauth-v1"},{"line":6,"text":"case \"$STAGE\" in /var/lib/homelab-admin/rollback/\"$TASK_ID\") ;; *) exit 64 ;; esac"},{"line":9,"text":"test -s \"$STAGE/health.txt\""},{"line":17,"text":"test \"$(sha256sum /usr/local/sbin/skladchik-reports-monitor-cookie-update-edge | awk '{print $1}')\" = \"$EXPECTED_SHA\""}],"path":"tasks/skladchik-reports-monitor-controlled-reauth-v1/assets/edge-dry-run.sh","present":true,"sha256":"ca42f68133086af7afd78a6d65e54a905a0ac9cfe583b867a98cd121addf732f"}],"output_truncated_in_json":false,"prerequisites":{"repo":{"head":"60f53ea6fe6724196802a46de3de19c7889a51cc","path":"/srv/homelab-ops-worktrees/cr-2026-0015","symbolic_head":"refs/heads/cr-2026-0015-pve03-r8152-rx-ring-canary","verified":true},"supervisor_path":"/usr/local/sbin/skladchik-reports-monitor-supervisor","supervisor_sha256":"bd40ee19ea8b277d52f4240b97d3c79b825c90154272bac8a43004591bd0ddc3","supervisor_sha_verified":true,"unit_path":"/etc/systemd/system/skladchik-reports-monitor-supervisor.service","unit_sha256":"e874fb03573b76181f3eb812c7285848e60705923c172a2f102504a7b9100ef7","unit_sha_verified":true},"projection_bytes":14930,"rc":0,"read_only":true,"rollback_restored":null,"rollback_started":false,"root_cause_classification":"EDGE_EXECUTION_PATH_INCOMPLETE","schema":1,"ssh_metadata":{"artifacts":[{"bytes":117,"is_symlink":false,"mode":"0o640","path":"[SENSITIVE_PATH] / \"health.txt\""}},{"line":16,"name":"STATE","value":{"expression":"STATE_DIR / \"state.env\""}},{"line":17,"name":"LOG","value":{"expression":"LOG_DIR / \"supervisor.log\""}},{"line":19,"name":"MONITOR_HEALTH_AGE_MAX","value":{"expression":"int(os.environ.get(\"SKLADCHIK_MONITOR_HEALTH_MAX_SECONDS\", \"600\"))"}},{"line":20,"name":"BACKUP_HEALTH_AGE_MAX","value":{"expression":"int(os.environ.get(\"SKLADCHIK_BACKUP_HEALTH_MAX_SECONDS\", \"129600\"))"}},{"line":21,"name":"RESTORE_HEALTH_AGE_MAX","value":{"expression":"int(os.environ.get(\"SKLADCHIK_RESTORE_HEALTH_MAX_SECONDS\", \"691200\"))"}},{"line":22,"name":"COOKIE_EXPIRY_WARN_SECONDS","value":{"expression":"int(os.environ.get(\"SKLADCHIK_COOKIE_EXPIRY_WARN_SECONDS\", \"604800\"))"}},{"line":24,"name":"PVE_BACKUP_HEALTH","value":"/var/lib/skladchik-reports-monitor-backup/health.txt"},{"line":25,"name":"PVE_RESTORE_HEALTH","value":"/var/lib/skladchik-reports-monitor-backup/restore-check-health.txt"}],"ast_parsed":true,"edge_assignment_present":true,"execution_excerpts":[{"line":12,"text":"EDGE = os.environ.get(\"SKLADCHIK_EDGE\", \"debian@\")"},{"line":13,"text":"STATE_DIR = Path(\"/var/lib/skladchik-reports-monitor-supervisor\")"},{"line":14,"text":"LOG_DIR = Path(\"/var/log/skladchik-reports-monitor-supervisor\")"},{"line":15,"text":"HEALTH = STATE_DIR / \"health.txt\""},{"line":19,"text":"MONITOR_HEALTH_AGE_MAX = int(os.environ.get(\"SKLADCHIK_MONITOR_HEALTH_MAX_SECONDS\", \"600\"))"},{"line":20,"text":"BACKUP_HEALTH_AGE_MAX = int(os.environ.get(\"SKLADCHIK_BACKUP_HEALTH_MAX_SECONDS\", \"129600\"))"},{"line":21,"text":"RESTORE_HEALTH_AGE_MAX = int(os.environ.get(\"SKLADCHIK_RESTORE_HEALTH_MAX_SECONDS\", \"691200\"))"},{"line":22,"text":"COOKIE_EXPIRY_WARN_SECONDS = int(os.environ.get(\"SKLADCHIK_COOKIE_EXPIRY_WARN_SECONDS\", \"604800\"))"},{"line":24,"text":"PVE_BACKUP_HEALTH = Path(\"/var/lib/skladchik-reports-monitor-backup/health.txt\")"},{"line":25,"text":"PVE_RESTORE_HEALTH = Path(\"/var/lib/skladchik-reports-monitor-backup/restore-check-health.txt\")"},{"line":73,"text":"def ssh_edge(cmd, timeout=45):"},{"line":74,"text":"q = \"ssh -o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=[SENSITIVE_PATH] \" + shlex.quote(EDGE) + \" \" + shlex.quote(\"sudo bash -lc \" + shlex.quote(cmd))"},{"line":77,"text":"def edge_mail(subject, body):"}],"functions":[{"args":["msg"],"contains_cookie":false,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":false,"line":33,"name":"log"},{"args":["cmd","timeout"],"contains_cookie":false,"contains_ssh":true,"contains_subprocess":false,"contains_systemctl":false,"line":73,"name":"ssh_edge"},{"args":["subject","body"],"contains_cookie":false,"contains_ssh":true,"contains_subprocess":false,"contains_systemctl":false,"line":77,"name":"edge_mail"},{"args":["units"],"contains_cookie":false,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":true,"line":94,"name":"systemctl_props"},{"args":[],"contains_cookie":true,"contains_ssh":true,"contains_subprocess":false,"contains_systemctl":true,"line":105,"name":"gather"},{"args":["status","facts","problems","mode"],"contains_cookie":true,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":false,"line":284,"name":"render_body"},{"args":["status","facts","problems","mail_sent"],"contains_cookie":false,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":false,"line":334,"name":"write_health"},{"args":[],"contains_cookie":false,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":false,"line":342,"name":"read_state"},{"args":["status","problems"],"contains_cookie":false,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":false,"line":345,"name":"write_state"},{"args":[],"contains_cookie":false,"contains_ssh":false,"contains_subprocess":false,"contains_systemctl":false,"line":349,"name":"main"}],"paths":["/dev/null","/etc/skladchik-reports-monitor/config.ini","/etc/skladchik-reports-monitor/secrets.env","/opt/skladchik-reports-monitor/event-selftest-core","/opt/skladchik-reports-monitor/event-selftest-runner.py","/opt/skladchik-reports-monitor/monitor.py","/opt/skladchik-reports-monitor/operational_digest.py","[SENSITIVE_PATH] = os.environ.get(\"SKLADCHIK_EDGE\", \"debian@\")"},{"line":73,"text":"def ssh_edge(cmd, timeout=45):"},{"line":74,"text":"q = \"ssh -o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=[SENSITIVE_PATH] \" + shlex.quote(EDGE) + \" \" + shlex.quote(\"sudo bash -lc \" + shlex.quote(cmd))"},{"line":77,"text":"def edge_mail(subject, body):"},{"line":90,"text":"rc, out = ssh_edge(\"python3 -c \" + shlex.quote(py), timeout=60)"},{"line":109,"text":"edge_cmd = r'''"},{"line":149,"text":"rc, out = ssh_edge(edge_cmd, timeout=45)"},{"line":150,"text":"facts[\"edge_ssh_rc\"] = str(rc)"},{"line":152,"text":"problems.append(\"edge_ssh_failed\")"}],"ssh_function_present":true,"top_level_import_safe":true,"units":["skladchik-reports-monitor-age-alert.timer","skladchik-reports-monitor-event-selftest.timer","skladchik-reports-monitor-heartbeat.timer","skladchik-reports-monitor-watchdog.timer","skladchik-reports-monitor-weekly-summary.timer","skladchik-reports-monitor.timer"]}} +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z","command_rc":1,"control_plane_error":null,"mutation_outcome":"NO_MUTATION","rc":1,"rollback_restored":false,"rollback_started":false,"status":"FAIL","version":1} +{"changes_made":false,"command_id":"HOMELAB-CLUSTER-ADMIN-UPDATES-V7-ARCHITECTURE-READ-ONLY-20260805T103600Z","error":"V6 output cardinality contracts=1 reports=0","error_type":"RuntimeError","mutation_outcome":"NO_MUTATION","read_only":true,"rollback_restored":false,"rollback_started":false,"schema":7,"status":"FAIL"} OUTPUT_END CHAT_OUTPUT_END