From 7766dd756cf60f9dafa9dd57330d2b1fd3bafbea Mon Sep 17 00:00:00 2001 From: homelab-runtime-publisher Date: Wed, 16 Sep 2026 21:13:43 +0000 Subject: [PATCH] runtime: publish SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1 --- ...IVE-ACTION-TRANSACTIONAL-CANARY-484R1.json | 38 ++++++++++++ ...TIVE-ACTION-TRANSACTIONAL-CANARY-484R1.txt | 44 ++++++++++++++ runtime/latest.json | 30 +++++----- runtime/latest.txt | 59 ++++++++----------- 4 files changed, 121 insertions(+), 50 deletions(-) create mode 100644 runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.json create mode 100644 runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.txt diff --git a/runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.json b/runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.json new file mode 100644 index 00000000..da6954b5 --- /dev/null +++ b/runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "change", + "component": "xenforo-app-policy-native-action-transactional-canary", + "started_at_utc": "2026-09-16T21:13:41Z", + "finished_at_utc": "2026-09-16T21:13:42Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "d835baf1e739fa0fa6c94345f2ad0697814f32ff5efb76eaece0af78c6bb21c6", + "duplicate_failed_command_blocked": false, + "block_reason": null, + "execution_started": true, + "change_declared": true, + "result_contract_valid": true, + "result_contract_status": "OK", + "result_contract_error": null, + "command_rc": 0, + "changes_made": true, + "rollback_started": true, + "rollback_restored": true, + "mutation_outcome": "ROLLED_BACK", + "sanitized": true, + "secrets_included": false, + "private_addresses_included": false, + "raw_evidence_retained_locally": true, + "raw_evidence_sha256": "0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9", + "sanitized_output_sha256": "0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "APP484_BEGIN\nAPP484_DECISION=PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK\nAPP484_NEXT_GATE=READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1\nAPP484_CANARY_DOMAIN=codevipe.ru\nAPP484_NATIVE_ACTION_PATHS_EXERCISED=2\nAPP484_ENTITY_SAVE_CALLS=3\nAPP484_ROLLBACK_STARTED=True\nAPP484_ROLLBACK_RESTORED=True\nAPP484_PERSISTENT_DRIFT_DETECTED=False\nAPP484_SAFE_REPORT={\"aggregate_restored\":true,\"anchor_483_commit\":\"6e5d92e225838298271af5e98956767c04fc065c\",\"anchor_483_decision\":\"PASS_NATIVE_ACTION_SEMANTICS_INVENTORY_READY\",\"auto_mutation_authorized\":false,\"backup_dr_mutations\":0,\"bounce_mid_visible\":true,\"canary_domain\":\"codevipe.ru\",\"changes_made\":true,\"command_id\":\"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1\",\"commit_operations\":0,\"database_mutations\":2,\"decision\":\"PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK\",\"dns_mutations\":0,\"domain\":\"codevipe.ru\",\"entity_api_canary\":true,\"entity_save_calls\":3,\"failure_label\":\"\",\"initial_receive_admin_email\":0,\"initial_user_state\":\"valid\",\"mail_mutations\":0,\"mail_send_operations\":0,\"native_action_paths_exercised\":2,\"native_bounce_processor_invoked\":false,\"native_bounce_processor_presence_gated\":true,\"next_gate\":\"READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1\",\"ok\":true,\"persistent_drift_detected\":false,\"persistent_mutation_authorized\":false,\"postbox_mutations\":0,\"processor_method_parameter_count\":1,\"processor_method_present\":true,\"processor_method_tokens_ok\":true,\"qga_160_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"qga_160_stdout_sha256\":\"d0e40b371b64a28a74d8ee38ab3eeb27c5b7942835c1e744414b4dff617cc911\",\"qga_160_transport_rc\":0,\"raw_sql_write_operations\":0,\"rollback_restored\":true,\"rollback_started\":true,\"selected_fields_restored\":true,\"subject_class\":\"VALID_NONBANNED_NONPRIVILEGED_WITH_OPTION_ROW\",\"transactional_rollback_only\":true,\"unsubscribe_false_mid_visible\":true,\"unsubscribe_roundtrip_from_zero\":true,\"xenforo_mutations\":2,\"xf_version_id\":2031170,\"xf_version_string\":\"2.3.11\"}\nHOMELAB_RESULT_CONTRACT={\"changes_made\":true,\"command_id\":\"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1\",\"rollback_restored\":true,\"rollback_started\":true,\"status\":\"OK\",\"version\":1}\nAPP484_END\n" +} diff --git a/runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.txt b/runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.txt new file mode 100644 index 00000000..99e9ce67 --- /dev/null +++ b/runtime/history/SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1.txt @@ -0,0 +1,44 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1 +STATUS=OK +RC=0 +HOST=pve01 +MODE=change +COMPONENT=xenforo-app-policy-native-action-transactional-canary +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=d835baf1e739fa0fa6c94345f2ad0697814f32ff5efb76eaece0af78c6bb21c6 +DUPLICATE_FAILED_COMMAND_BLOCKED=false +EXECUTION_STARTED=true +CHANGE_DECLARED=true +RESULT_CONTRACT_VALID=true +RESULT_CONTRACT_STATUS=OK +RESULT_CONTRACT_ERROR=NONE +COMMAND_RC=0 +CHANGES_MADE=true +ROLLBACK_STARTED=true +ROLLBACK_RESTORED=true +MUTATION_OUTCOME=ROLLED_BACK +SANITIZED=yes +SECRETS_INCLUDED=no +PRIVATE_ADDRESSES_INCLUDED=no +RAW_EVIDENCE_SHA256=0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9 +SANITIZED_OUTPUT_SHA256=0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9 +OUTPUT_BEGIN +APP484_BEGIN +APP484_DECISION=PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK +APP484_NEXT_GATE=READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1 +APP484_CANARY_DOMAIN=codevipe.ru +APP484_NATIVE_ACTION_PATHS_EXERCISED=2 +APP484_ENTITY_SAVE_CALLS=3 +APP484_ROLLBACK_STARTED=True +APP484_ROLLBACK_RESTORED=True +APP484_PERSISTENT_DRIFT_DETECTED=False +APP484_SAFE_REPORT={"aggregate_restored":true,"anchor_483_commit":"6e5d92e225838298271af5e98956767c04fc065c","anchor_483_decision":"PASS_NATIVE_ACTION_SEMANTICS_INVENTORY_READY","auto_mutation_authorized":false,"backup_dr_mutations":0,"bounce_mid_visible":true,"canary_domain":"codevipe.ru","changes_made":true,"command_id":"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1","commit_operations":0,"database_mutations":2,"decision":"PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK","dns_mutations":0,"domain":"codevipe.ru","entity_api_canary":true,"entity_save_calls":3,"failure_label":"","initial_receive_admin_email":0,"initial_user_state":"valid","mail_mutations":0,"mail_send_operations":0,"native_action_paths_exercised":2,"native_bounce_processor_invoked":false,"native_bounce_processor_presence_gated":true,"next_gate":"READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1","ok":true,"persistent_drift_detected":false,"persistent_mutation_authorized":false,"postbox_mutations":0,"processor_method_parameter_count":1,"processor_method_present":true,"processor_method_tokens_ok":true,"qga_160_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","qga_160_stdout_sha256":"d0e40b371b64a28a74d8ee38ab3eeb27c5b7942835c1e744414b4dff617cc911","qga_160_transport_rc":0,"raw_sql_write_operations":0,"rollback_restored":true,"rollback_started":true,"selected_fields_restored":true,"subject_class":"VALID_NONBANNED_NONPRIVILEGED_WITH_OPTION_ROW","transactional_rollback_only":true,"unsubscribe_false_mid_visible":true,"unsubscribe_roundtrip_from_zero":true,"xenforo_mutations":2,"xf_version_id":2031170,"xf_version_string":"2.3.11"} +HOMELAB_RESULT_CONTRACT={"changes_made":true,"command_id":"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1","rollback_restored":true,"rollback_started":true,"status":"OK","version":1} +APP484_END + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index 3f088a42..da6954b5 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,38 +1,38 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "SUPPORT-260916-INFRA-DR-BACKUPV2-LEGACY-PVE-RETENTION-SOURCE-CAPTURE-489R1", + "command_id": "SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1", "status": "OK", "rc": 0, "host": "pve01", - "mode": "read-only", - "component": "infra-dr-backupv2-legacy-pve-retention-source-capture", - "started_at_utc": "2026-09-16T20:58:04Z", - "finished_at_utc": "2026-09-16T20:58:05Z", + "mode": "change", + "component": "xenforo-app-policy-native-action-transactional-canary", + "started_at_utc": "2026-09-16T21:13:41Z", + "finished_at_utc": "2026-09-16T21:13:42Z", "reference_register_checked": true, "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", "error_register_checked": true, "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "45aee1dd4582048afc3a1893c770533d881e663514524acddbccf3a9685edc9b", + "command_sha256": "d835baf1e739fa0fa6c94345f2ad0697814f32ff5efb76eaece0af78c6bb21c6", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, - "change_declared": false, + "change_declared": true, "result_contract_valid": true, - "result_contract_status": null, + "result_contract_status": "OK", "result_contract_error": null, "command_rc": 0, - "changes_made": false, - "rollback_started": false, - "rollback_restored": null, - "mutation_outcome": "NO_MUTATION", + "changes_made": true, + "rollback_started": true, + "rollback_restored": true, + "mutation_outcome": "ROLLED_BACK", "sanitized": true, "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "87ab0715c0a1ecdb6af4b9bca6d13dea8fee4e52aa04edf113ad69329149d286", - "sanitized_output_sha256": "7c8ac17b371d7c485cbd9c1a7c4097ffa6cf649306bdb7ee68326ee8d9484e9c", + "raw_evidence_sha256": "0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9", + "sanitized_output_sha256": "0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "COMMAND_ID=SUPPORT-260916-INFRA-DR-BACKUPV2-LEGACY-PVE-RETENTION-SOURCE-CAPTURE-489R1\nSCOPE=READ_ONLY_SOURCE_AUTHORITY_CAPTURE_NO_BACKUP_NO_CLOUD_NO_MUTATION\nIDENTITIES={\"adapter\":\"18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3\",\"engine\":\"dbfd237ddae5d2199bd8567ec6880d11276631dcc45acb49967de97329524037\",\"gfs\":null,\"legacy\":\"b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7\",\"policy\":\"e06b7e6285eda2885ef913aa954a70abc7c1d892199a8b7cea2ada98b8edba34\",\"pve265\":\"cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be\",\"pve270\":\"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\",\"retention\":\"8adb6c10f5911f39c53775b89eac3cd1823f1ed34b4caccade5279c213e998a3\",\"seal\":\"f508adc9b09bad9692c580e642018f5d3dbf223fc572ee62478466fd517234fa\",\"targets\":\"a723befc7fd42d70af9088406598f18156dc3b4c76d8b34c4bb725dfaa48dd38\"}\nBASELINE_MATCH={\"engine\":true,\"retention\":true,\"seal\":true,\"targets\":true}\nLEGACY_CAPTURE_PVE_GUEST={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py\",\"file_sha256\":\"b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7\",\"lines\":[\"def capture_pve_guest(t,gen,work):\",\" vmid=int(t['vmid']); rows=[r for r in cluster_inventory() if int(r.get('vmid',-1))==vmid]\",\" if len(rows)!=1: raise BackupError('PVE_GUEST_NOT_UNIQUE')\",\" row=rows[0]; node=row.get('node'); typ=row.get('type')\",\" if typ!=t['guest_type']: raise BackupError('PVE_GUEST_TYPE_DRIFT')\",\" if typ=='lxc':\",\" _require_exact_source(P270,P270_SHA,'P270_IDENTITY');_require_exact_source(P282,P282_SHA,'P282_IDENTITY')\",\" _default_unprivileged_lxc(node,vmid)\",\" scratch=f'/var/tmp/homelab-vzdump-v2-{gen}'\",\" ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)\",\" q=ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)\",\" if q.stdout.decode().strip()!='710:0:100000': raise BackupError('PVE_MAPPED_SCRATCH_ACCESS_CONTRACT')\",\" try:\",\" mapped_scratch_probe(node,scratch)\",\" argv,job=proven_lxc_dump_argv(t,row,node,scratch)\",\" local=work/'payload.bin'\",\" _stream_argv_to_local(node,argv,local,timeout=7200)\",\" if local.stat().st_size>int(job['archive_cap_bytes']): raise BackupError('VZDUMP_ARCHIVE_CAP_EXCEEDED')\",\" except Exception:\",\" ssh_remote(node,['rm','-rf','--',scratch],timeout=60,check=False);raise\",\" cleanup={'kind':'pve_source_dir','node':node,'path':scratch}\",\" return local,{'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':typ,'node':node,'status':row.get('status'),'producer_contract':'proven-270-282-stream'},cleanup\",\" # QEMU path remains unchanged: bounded dedicated dumpdir with later cloud readback/reconstruction.\",\" srcdir=f'/var/tmp/homelab-vzdump-v2-{gen}'\",\" ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)\",\" try:\",\" ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200)\",\" p=ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\\\\n'],timeout=30)\",\" files=[x for x in p.stdout.decode().splitlines() if x.strip()]\",\" if len(files)!=1: raise BackupError('VZDUMP_OUTPUT_NOT_UNIQUE')\",\" src=files[0];local=work/'payload.bin'\",\" if node=='pve01': local=pathlib.Path(src)\",\" else: run([SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)\",\" if not pathlib.Path(local).is_file() or pathlib.Path(local).stat().st_size<=0: raise BackupError('VZDUMP_PAYLOAD_MISSING')\",\" except Exception:\",\" ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False);raise\",\" return pathlib.Path(local),{'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':typ,'node':node,'status':row.get('status')},{'kind':'pve_source_dir','node':node,'path':srcdir}\"],\"name\":\"capture_pve_guest\",\"source_sha256\":\"c4c22625a9c6a954d0ed93dfc63f0501af0644ca9f5e6781d3b2e50a7e2563ea\"}\nLEGACY_CAPTURE_TARGET={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py\",\"file_sha256\":\"b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7\",\"lines\":[\"def capture_target(t,gen,work):\",\" typ=t['type']\",\" if typ=='pve_guest': return capture_pve_guest(t,gen,work)\",\" if typ=='pve_node_bundle': return capture_node_bundle(t,gen,work)\",\" if typ=='vps_md': return capture_vps_md(t,gen,work)\",\" if typ=='vps_spb': return capture_vps_spb(t,gen,work)\",\" if typ=='vps_us': return capture_vps_us(t,gen,work)\",\" if typ=='router': return capture_router(t,gen,work)\",\" if typ=='xenforo': return capture_xenforo(t,gen,work)\",\" raise BackupError('CAPTURE_TYPE_UNKNOWN')\"],\"name\":\"capture_target\",\"source_sha256\":\"f52cec3a28467da247da0efaffb9523a775b1bb0cab2ce7fef1b1a5923a765bb\"}\nPVE265_DUMP_ARGV={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py\",\"file_sha256\":\"cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be\",\"lines\":[\"def dump_argv(job,executable,tmpdir,now):\",\" validate_job(job,now)\",\" need(path_ok(executable) and path_ok(tmpdir),'EXECUTION_PATH')\",\" return [str(executable),str(job['vmid']),'--node',job['node'],'--mode','snapshot','--stdout','1',\",\" '--compress','zstd','--zstd','1','--remove','0','--prune-backups','keep-all=1',\",\" '--stdexcludes','0','--lockwait','0','--bwlimit','32768','--ionice','7','--tmpdir',str(tmpdir)]\"],\"name\":\"dump_argv\",\"source_sha256\":\"5244bbe02f2fc966e08b6c71ffc8430cedfb66635864e8994f8bcc3a1483cd93\"}\nPVE270_HOST_MAPPING={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py\",\"file_sha256\":\"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\",\"lines\":[\"def host_mapping():\",\" # Scope of the exception is this observed, protected system ELF pair only.\",\" # PVE modules and private data retain the original single-link reader.\",\" pins={p:t.sha(t.read_secure(Path(p),2*1024**2)[0]) for p in\",\" ('/usr/share/perl5/PVE/LXC.pm','/usr/share/perl5/PVE/VZDump/LXC.pm')}\",\" code=('my($m,$u,$g)=PVE::LXC::parse_id_maps({unprivileged=>1,lxc=>[]});'\",\" 'print JSON::PP->new->canonical->encode({root_uid=>0+$u,root_gid=>0+$g,'\",\" 'id_map=>[map {[$_->[0],0+$_->[1],0+$_->[2],0+$_->[3]]} @$m]});')\",\" with PerlPin('/usr/bin/perl','/usr/bin/perl5.40.1') as pin:\",\" rc,b=pin.run(['-MPVE::LXC','-MJSON::PP','-e',code])\",\" need(rc==0,'PVE_IDMAP_READ_FAILED')\",\" for p,h in pins.items():need(t.sha(t.read_secure(Path(p),2*1024**2)[0])==h,'PVE_MAPPING_SOURCE_CHANGED')\",\" pin.check()\",\" try:d=json.loads(b)\",\" except (ValueError,UnicodeError):raise old.PVEError('PVE_IDMAP_JSON') from None\",\" return validate_mapping(d)\"],\"name\":\"host_mapping\",\"source_sha256\":\"3594394c852f13ba57e3c1ae623a071352d95d2dac35bfba6bb6af73d5783f0a\"}\nPVE270_VALIDATE_MAPPING={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py\",\"file_sha256\":\"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\",\"lines\":[\"def validate_mapping(d):\",\" need(type(d) is dict and set(d)=={'root_uid','root_gid','id_map'},'IDMAP_SCHEMA')\",\" need(type(d['root_uid']) is int and type(d['root_gid']) is int,'IDMAP_VALUE')\",\" need(d['root_uid']==d['root_gid']==100000,'ONLY_DEFAULT_UNPRIVILEGED_IDMAP')\",\" expect=[['u',0,100000,65536],['g',0,100000,65536]]\",\" need(type(d['id_map']) is list and len(d['id_map'])==2,'IDMAP_ROWS')\",\" for row,exp in zip(d['id_map'],expect):\",\" need(type(row) is list and len(row)==4 and type(row[0]) is str and all(type(n) is int for n in row[1:]) and row==exp,'IDMAP_NONDEFAULT')\",\" return d['root_uid'],d['root_gid']\"],\"name\":\"validate_mapping\",\"source_sha256\":\"461ec78d3d02e1d590ed62baee4a278976d9737a88f08e4a4030d702a0be1ef3\"}\nPVE270_CAPTURE_ARCHIVE={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py\",\"file_sha256\":\"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\",\"lines\":[\"def capture_archive(argv,destination,cap,seconds,check):\",\" \\\"\\\"\\\"Same streaming bounds as 265; stderr kept privately, child-only umask=022.\\\"\\\"\\\"\",\" need(type(argv) is list and argv and all(type(x) is str for x in argv),'ARGV')\",\" need(type(cap) is int and 0=next_check:check();next_check=now+0.5\",\" for key,_ in sel.select(min(0.1,max(0,deadline-now))):\",\" b=os.read(key.fileobj.fileno(),65536)\",\" if not b:sel.unregister(key.fileobj);continue\",\" if key.fileobj is p.stdout:\",\" need(total+len(b)<=cap,'ARCHIVE_CAP_REACHED_PARTIAL_RETAINED')\",\" stream.write_all(fd,b);digest.update(b);total+=len(b)\",\" else:\",\" err_total+=len(b);eh.update(b);chunk=b[:max(0,MAX_STDERR-err_kept)]\",\" if chunk:stream.write_all(efd,chunk);err_kept+=len(chunk)\",\" need(deadline>time.monotonic(),'PRODUCER_TIMEOUT')\",\" try:rc=p.wait(timeout=deadline-time.monotonic())\",\" except subprocess.TimeoutExpired:raise old.PVEError('PRODUCER_TIMEOUT') from None\",\" need(rc==0,'PRODUCER_RC_FAILED_PARTIAL_RETAINED');need(total>0,'EMPTY_ARCHIVE');check()\",\" st=os.fstat(fd);named=os.stat(dest.name,dir_fd=parent,follow_symlinks=False)\",\" need(st.st_dev==initial.st_dev and st.st_ino==initial.st_ino and t.ident(st)==t.ident(named) and st.st_nlink==1 and st.st_size==total,'PRODUCER_FILE_IDENTITY_CHANGED')\",\" os.fchmod(fd,0o400);os.fsync(fd);os.fsync(parent);good=True\",\" return {'size':total,'sha256':digest.hexdigest(),'producer_rc':rc,'identity':list(t.ident(os.fstat(fd)))}\",\" finally:\",\" if p is not None:\",\" if p.poll() is None:old.terminate(p)\",\" p.wait();p.stdout.close();p.stderr.close()\",\" if sel is not None:sel.close()\",\" try:\",\" if fd is not None:os.fsync(fd)\",\" if efd is not None:os.fsync(efd)\",\" if owned:\",\" summary={'process_started':p is not None,'producer_rc':p.returncode if p is not None else None,\",\" 'capture_success':good,'archive_bytes':total,'stderr_bytes_observed':err_total,\",\" 'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,\",\" 'stderr_stream_sha256':eh.hexdigest(),'raw_stderr_exported':False,'child_umask':'0022'}\",\" t.create(dest.parent/'PRODUCER_PROCESS.json',core.canonical_bytes(summary))\",\" finally:\",\" if fd is not None:os.close(fd)\",\" if efd is not None:os.close(efd)\",\" os.close(parent)\"],\"name\":\"capture_archive\",\"source_sha256\":\"795afc9f2c9f3ff0691680362771f703506295588e6f6b73dfb7e68addded6e7\"}\nPVE270_PRODUCE={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py\",\"file_sha256\":\"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\",\"lines\":[\"def produce(job,work,tools,guard,*,mapping,seconds=14400,emit=lambda k,v:None):\",\" need(callable(guard),'GUARD_REQUIRED');guard();old.validate_job(job,int(time.time()));old.validate_tools(tools)\",\" need(job.get('vmid')==110 and job.get('type')=='lxc' and job.get('config_sha256')==EXPECTED_CFG,'ONLY_ACCEPTED_CT110')\",\" uid,gid=validate_mapping(mapping)\",\" work=Path(work);parent=stream.private_dir(work)\",\" try:need(os.listdir(parent)==[],'PRODUCER_WORKSPACE_NOT_EMPTY')\",\" finally:os.close(parent)\",\" # Keep the old orchestration contract: this private placeholder stays empty.\",\" t.make_dir(work/'tmp',exclusive=True)\",\" scratch=None;complete=False\",\" try:\",\" scratch=MappedScratch(gid)\",\" emit('PVE_TEMP_DIRECTORY',scratch.path);emit('PVE_TEMP_MODE','0710');emit('PVE_TEMP_GID',gid)\",\" t.create(work/'PVE_TEMP.json',core.canonical_bytes({'path':str(scratch.path),'mode':'0710','uid':0,'gid':gid,'identity':list(scratch.identity)}))\",\" scratch.probe(uid,work);emit('MAPPED_UID_ACCESS_AND_ISOLATION_PROBE','PASS')\",\" def free_guard():\",\" scratch.check()\",\" for path,reserve,reason in ((work,old.LOCAL_RESERVE,'STAGING_RESERVE_REACHED_PARTIAL_RETAINED'),(scratch.path,256*1024**2,'PVE_TEMP_RESERVE_LOW')):\",\" v=os.statvfs(path);need(v.f_frsize*v.f_bavail>=reserve,reason)\",\" free_guard();guard();dest=work/'guest-110.tar.zst'\",\" result=capture_archive(old.dump_argv(job,tools['vzdump']['path'],scratch.path,int(time.time())),dest,job['archive_cap_bytes'],seconds,free_guard)\",\" guard();old.validate_tools(tools)\",\" rc,_=t.bounded_process([tools['zstd']['path'],'--test','--quiet','--',str(dest)],dict(old.ENV),65536,min(seconds,3600))\",\" need(rc==0,'ARCHIVE_COMPRESSION_TEST_FAILED_RETAINED')\",\" n,h,identity=stream.hash_file(dest,job['archive_cap_bytes'])\",\" need(n==result['size'] and h==result['sha256'] and list(identity)==result['identity'],'PRODUCER_READBACK_MISMATCH')\",\" guard();old.validate_tools(tools);scratch.close(empty_only=True);complete=True;emit('PVE_TEMP_EMPTY_REMOVED','YES')\",\" return {**result,'path':str(dest),'vmid':110,'type':'lxc','node':job['node'],'config_sha256':job['config_sha256'],\",\" 'compression_test_ok':True,'restored':False,'state':'PRODUCED_COMPRESSION_CHECKED_NOT_CLOUD_SEALED','local_payload_retained':True}\",\" finally:\",\" m=work/'PRODUCER_PROCESS.json'\",\" if m.exists():\",\" info=json.loads(t.read_secure(m,65536,private=True)[0])\",\" emit('VZDUMP_PROCESS_STARTED','YES' if info.get('process_started') else 'NO')\",\" emit('VZDUMP_PROCESS_RC',info.get('producer_rc'));emit('PRIVATE_STDERR_BYTES',info.get('stderr_bytes_retained'))\",\" if scratch is not None and not complete:\",\" emit('PVE_TEMP_RETAINED','YES');scratch.close(empty_only=False)\"],\"name\":\"produce\",\"source_sha256\":\"5278bae09546a659401348335cf2d0834f49d372727a4751245ead6a3aa27a79\"}\nPVE270_LIVE_GATE={\"file\":\"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py\",\"file_sha256\":\"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\",\"lines\":[\"def live_gate(job,pvesh_path,pvesh_sha):\",\" need(job.get('vmid')==110 and job.get('type')=='lxc' and job.get('node')=='pve01' and job.get('config_sha256')==EXPECTED_CFG,'ONLY_ACCEPTED_CT110')\",\" vals=[]\",\" for part in ('config','status/current','snapshot'):\",\" need(t.sha(t.read_secure(Path(pvesh_path),16*1024**2)[0])==pvesh_sha,'PVESH_CHANGED')\",\" rc,b=t.bounded_process([str(pvesh_path),'get','/nodes/pve01/lxc/110/'+part,'--output-format','json'],dict(old.ENV),262144,30)\",\" need(rc==0,'CT_GATE_READ_FAILED')\",\" try:vals.append(json.loads(b))\",\" except (ValueError,UnicodeError):raise old.PVEError('CT_GATE_JSON') from None\",\" validate_ct(*vals,job['config_sha256'])\",\" return True\"],\"name\":\"live_gate\",\"source_sha256\":\"5ec8790c2633c8e576ddecfc04d7878ce7a5ee8ee2de5097dd664245f6621ac0\"}\nADAPTER_CONTEXT={\"bytes\":2989,\"file_sha256\":\"18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3\",\"lines\":[\"11:'pve265.py':'cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be',\",\"12:'guest266.py':'86433bc424d5fa5017c20f7a237c82874b02357a3283660d8a6b0039ef2bc868',\",\"13:'pve270.py':'97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef',\",\"14:'pve282.py':'73c6cb7773eb8e82d1e7ed5ab4733b4afb88f74ae69c09125d0378d6e480e012'}\",\"15:def sha(p):\",\"23: if not p.is_file() or p.is_symlink() or sha(p)!=want:raise RuntimeError('SOURCE_IDENTITY_'+name)\",\"24:def load_graph():\",\"25: import guest266,pve265,pve270,pve282\",\"26: if hasattr(guest266,'dump_argv'):raise RuntimeError('GUEST266_UNEXPECTED_DUMP_ARGV')\",\"27: if not hasattr(pve265,'dump_argv'):raise RuntimeError('PVE265_DUMP_ARGV_MISSING')\",\"28: if getattr(pve270,'old',None) is not pve265:raise RuntimeError('PVE270_OLD_NOT_PVE265')\",\"29: if getattr(pve282,'old',None) is not pve265:raise RuntimeError('PVE282_OLD_NOT_PVE265')\",\"30: if getattr(pve282,'proven',None) is not pve270:raise RuntimeError('PVE282_PROVEN_NOT_PVE270')\",\"31: for n in ('MappedScratch','capture_archive','validate_mapping'):\",\"32: if not hasattr(pve270,n):raise RuntimeError('PVE270_'+n.upper()+'_MISSING')\",\"33: if getattr(pve282,n,None) is not getattr(pve270,n):raise RuntimeError('PVE282_ALIAS_'+n.upper()+'_MISMATCH')\",\"34: return guest266,pve265,pve270,pve282\",\"35:def describe():\",\"36: _,p265,p270,p282=load_graph()\",\"37: funcs={'pve265.dump_argv':p265.dump_argv,'pve265.validate_job':p265.validate_job,'pve265.make_plan':p265.make_plan,'pve270.validate_mapping':p270.validate_mapping,'pve270.capture_archive':p270.capture_archive,'pve270.produce':p270.produce,'pve282.select112':p282.select112,'pve282.produce':p282.produce}\",\"38: return {'schema':1,'bundle':'pve-lxc-adapter-411r1','source_sha256':EXPECTED,'signatures':{k:str(inspect.signature(v)) for k,v in funcs.items()},'owner':{'dump_argv':'pve265','MappedScratch':'pve270','capture_archive':'pve270','validate_mapping':'pve270','pve282.old':'pve265','pve282.proven':'pve270'}}\",\"39:def main():\",\"40: verify_sources(); mode=sys.argv[1] if len(sys.argv)>1 else 'selftest'; d=describe()\"],\"match_count\":10,\"state\":\"OK\"}\nRETENTION_CLI_FLAGS=[\"--arg\",\"--argjson\",\"--config\",\"--dirs-only\",\"--immutable\",\"--max-depth\",\"--size-only\"]\nGFS_CLI_FLAGS=[]\nRETENTION_SOURCE_CONTEXT={\"bytes\":32975,\"file_sha256\":\"8adb6c10f5911f39c53775b89eac3cd1823f1ed34b4caccade5279c213e998a3\",\"lines\":[\"21:REGISTRY_HELPER=\\\"${HOMELAB_BACKUP_TARGET_REGISTRY_HELPER:-/usr/local/libexec/homelab-backup-target-registry}\\\"\",\"22:REGISTRY_HELPER_SHA_EXPECTED=c681c44be7557d192d7b453b67e31164237874596168f1d4c78e1e926e2e9cb4\",\"23:GFS_HELPER=\\\"${HOMELAB_BACKUP_GFS_POLICY_HELPER:-/usr/local/libexec/homelab-backup-gfs-policy}\\\"\",\"24:GFS_HELPER_SHA_EXPECTED=6b7ec1ab3ee1c540a9113b5620c3b4b5a50de6536f3a069d31b2e1243f23bafa\",\"25:GFS_POLICY=\\\"${HOMELAB_BACKUP_GFS_POLICY:-/etc/homelab-backup/gfs-retention.json}\\\"\",\"26:CONTROL_EVIDENCE_ROOT=/var/lib/homelab-backup/control-restore-validation/control-bootstrap\",\"27:[[ -x \\\"$REGISTRY_HELPER\\\" && ! -L \\\"$REGISTRY_HELPER\\\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=TARGET_REGISTRY_HELPER_MISSING\\\\n' >&2; exit 69; }\",\"28:[[ \\\"$(sha256sum \\\"$REGISTRY_HELPER\\\"|awk '{print $1}')\\\" == \\\"$REGISTRY_HELPER_SHA_EXPECTED\\\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=TARGET_REGISTRY_HELPER_SHA_DRIFT\\\\n' >&2; exit 65; }\",\"29:\\\"$REGISTRY_HELPER\\\" validate >/dev/null || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=TARGET_REGISTRY_INVALID\\\\n' >&2; exit 66; }\",\"30:[[ -x \\\"$GFS_HELPER\\\" && ! -L \\\"$GFS_HELPER\\\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=GFS_POLICY_HELPER_MISSING\\\\n' >&2; exit 69; }\",\"31:[[ \\\"$(sha256sum \\\"$GFS_HELPER\\\"|awk '{print $1}')\\\" == \\\"$GFS_HELPER_SHA_EXPECTED\\\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=GFS_POLICY_HELPER_SHA_DRIFT\\\\n' >&2; exit 65; }\",\"32:HOMELAB_BACKUP_GFS_POLICY=\\\"$GFS_POLICY\\\" \\\"$GFS_HELPER\\\" validate >/dev/null || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=GFS_POLICY_INVALID\\\\n' >&2; exit 66; }\",\"33:GFS_WEEKLY=\\\"$(HOMELAB_BACKUP_GFS_POLICY=\\\"$GFS_POLICY\\\" \\\"$GFS_HELPER\\\" weekly-buckets)\\\"\",\"34:GFS_MONTHLY=\\\"$(HOMELAB_BACKUP_GFS_POLICY=\\\"$GFS_POLICY\\\" \\\"$GFS_HELPER\\\" monthly-buckets)\\\"\",\"35:GFS_CRITICAL_COUNT=\\\"$(HOMELAB_BACKUP_GFS_POLICY=\\\"$GFS_POLICY\\\" \\\"$GFS_HELPER\\\" critical-logicals | wc -l)\\\"\",\"36:VM_KEEP=\\\"$(\\\"$REGISTRY_HELPER\\\" policy-keep VM)\\\"\",\"37:APP_KEEP=\\\"$(\\\"$REGISTRY_HELPER\\\" policy-keep APP)\\\"\",\"38:CONTROL_KEEP=\\\"$(\\\"$REGISTRY_HELPER\\\" policy-keep CONTROL)\\\"\",\"39:MIN_DELETE_AGE_SECONDS=86400\",\"40:SSH_BASE=(-n -o BatchMode=yes -o ConnectTimeout=12 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=[SENSITIVE_PATH] local msg=\\\"$1\\\" rc=\\\"${2:-65}\\\"; trap - ERR; printf 'GC_STATUS=ERROR|ROOT_CAUSE=%s\\\\n' \\\"$msg\\\" >&2; exit \\\"$rc\\\"; }\",\"43:cleanup(){ if [[ -n \\\"${TMPROOT:-}\\\" && -d \\\"$TMPROOT\\\" ]]; then rm -rf -- \\\"$TMPROOT\\\"; fi; }\",\"44:stable_delete_set(){ sed -E 's/\\\\|age_seconds=[0-9]+$//'; }\",\"45:trap cleanup EXIT\",\"46:\",\"72:strict_state(){\",\"73: local json=\\\"$1\\\" logical=\\\"$2\\\" generation=\\\"$3\\\"\",\"74: jq -e --arg l \\\"$logical\\\" --arg g \\\"$generation\\\" '.schema==\\\"homelab-cloud-quorum-payload-v1\\\" and .logical_id==$l and .generation==$g and .status==\\\"SEALED\\\" and .cloud_quorum==2 and .cloud_a_verified==true and .cloud_b_verified==true and .part_hashes_verified==true and .seal_written==true and .cloud_a_seal_verified==true and .cloud_b_seal_verified==true and .local_delete_allowed==true and .local_payload_present==false and .local_cleanup==\\\"OK\\\"' <<<\\\"$json\\\" >/dev/null\",\"75:}\",\"76:latest_restore_proven(){\",\"121: case \\\"$status\\\" in\",\"122: DONE) ;;\",\"123: PLANNED|B_DELETED) count=$((count+1)) ;;\",\"124: *) die \\\"TX_STATUS_INVALID_$f\\\" ;;\",\"125: esac\",\"128:}\",\"129:\",\"130:pinned_delete_contract_enabled(){\",\"131: [[ -n \\\"${HOMELAB_RETENTION_PINNED_DELETE_FILE:-}\\\" || -n \\\"${HOMELAB_RETENTION_PINNED_DELETE_SHA256:-}\\\" ]]\",\"132:}\",\"133:pinned_delete_assert_file(){\",\"134: local f=\\\"${HOMELAB_RETENTION_PINNED_DELETE_FILE:-}\\\" expected=\\\"${HOMELAB_RETENTION_PINNED_DELETE_SHA256:-}\\\" actual line logical generation owner state_file state_sha count=0\",\"135: [[ -n \\\"$f\\\" && -n \\\"$expected\\\" ]] || die PINNED_DELETE_CONTRACT_INCOMPLETE 64\",\"136: [[ \\\"$expected\\\" =~ ^[0-9a-f]{64}$ ]] || die PINNED_DELETE_SHA_INVALID 64\",\"137: [[ -f \\\"$f\\\" && ! -L \\\"$f\\\" ]] || die PINNED_DELETE_FILE_UNSAFE 64\",\"138: actual=\\\"$(sha256sum \\\"$f\\\" | awk '{print $1}')\\\"\",\"139: [[ \\\"$actual\\\" == \\\"$expected\\\" ]] || die PINNED_DELETE_FILE_SHA_MISMATCH 66\",\"140: while IFS= read -r line; do\",\"141: [[ -n \\\"$line\\\" ]] || die PINNED_DELETE_EMPTY_LINE 66\",\"142: logical=\\\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^logical=/){sub(/^logical=/,\\\"\\\",$i);print $i}}' <<<\\\"$line\\\")\\\"\",\"143: generation=\\\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^generation=/){sub(/^generation=/,\\\"\\\",$i);print $i}}' <<<\\\"$line\\\")\\\"\",\"145: state_file=\\\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^state_file=/){sub(/^state_file=/,\\\"\\\",$i);print $i}}' <<<\\\"$line\\\")\\\"\",\"146: state_sha=\\\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^state_sha256=/){sub(/^state_sha256=/,\\\"\\\",$i);print $i}}' <<<\\\"$line\\\")\\\"\",\"147: [[ \\\"$line\\\" == \\\"DELETE|logical=$logical|generation=$generation|owner=$owner|state_file=$state_file|state_sha256=$state_sha\\\" ]] || die PINNED_DELETE_LINE_FORMAT_INVALID 66\",\"148: [[ \\\"$(node_for_logical \\\"$logical\\\")\\\" == \\\"$owner\\\" ]] || die \\\"PINNED_DELETE_OWNER_INVALID_${logical}\\\" 66\",\"149: safe_generation \\\"$logical\\\" \\\"$generation\\\" || die \\\"PINNED_DELETE_GENERATION_INVALID_${logical}\\\" 66\",\"150: [[ \\\"$state_file\\\" == \\\"$STATE_ROOT/$logical/$generation.json\\\" ]] || die \\\"PINNED_DELETE_STATE_PATH_INVALID_${logical}\\\" 66\",\"151: [[ \\\"$state_sha\\\" =~ ^[0-9a-f]{64}$ ]] || die \\\"PINNED_DELETE_STATE_SHA_INVALID_${logical}\\\" 66\"],\"match_count\":28,\"state\":\"OK\"}\nGFS_SOURCE_CONTEXT={\"state\":\"ABSENT\"}\nPOLICY_EVIDENCE={\"bytes\":1436,\"hits\":[],\"sha256\":\"e06b7e6285eda2885ef913aa954a70abc7c1d892199a8b7cea2ada98b8edba34\",\"top_keys\":[\"account_failure_domains\",\"accounts\",\"canary\",\"change_id\",\"cloud_retention\",\"failure_policy\",\"local_retention\",\"policy_id\",\"provider\",\"provider_failure_domains\",\"quorum\",\"restore_policy\",\"schema_version\"],\"top_type\":\"dict\"}\nOPS_REPO_EVIDENCE={\"branch\":{\"lines\":[\"main\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"6403203dd5a0867eb14d104ee8a73730bd72dd9ad92e78d996a6dba0a5dcfc01\"},\"current_lifecycle\":{\"lines\":[\"HEAD:kb/AI_CONTEXT.md:24:110 dns1, 111 dns2, 112 unbound1, 113 unbound2, VM130 edge-vm, VM150 Snikket, VM160 forum-prod, VM170 core-apps/Gitea, VM171 monitoring, VM190 Gitea Actions runner. VM180 and CT200 are retirement candidates only; no blind delete. VM9130 edge-cold-standby stays until timed VM130 DR restore proof.\",\"HEAD:kb/AI_CONTEXT.md:28:Inbound pvepro.ru mail is retired with Null MX. Outbound PHP/XenForo transport is Yandex Cloud Postbox via VM160 msmtp. Credential ref is `postbox_smtp_secret`; its storage metadata is private-facade data and the value never belongs in Git/chat. Five XenForo DBs require individual P0 application acceptance: `xf_codevipe`, `xf_dsmods`, `xf_gamevipe`, `xf_hkmods`, `xf_zakrutim`.\",\"HEAD:kb/AI_CONTEXT_PUBLIC.md:11:The homelab is a three-node Proxmox cluster with dedicated DNS/Unbound guests, EDGE VM, Snikket, forum production, core-apps/Gitea, monitoring and Gitea Actions runner. Retirement candidates and DR standby are not deletion-authorized merely because they are not primary production.\",\"HEAD:kb/AI_CONTEXT_PUBLIC.md:15:CR0083 is merged/closed. Current P0 sequence starts with Git topology preservation, then canonical post-migration state, recovery/backup refresh, VM160/forum acceptance, permanent new-USA SSH hardening, old-USA observation/retirement, and final seal.\",\"HEAD:kb/AI_CONTEXT_PUBLIC.md:19:- Inbound mail is intentionally retired with Null MX; outbound forum mail uses Yandex Cloud Postbox.\",\"HEAD:kb/changes/CR-2026-0086-HANDOFF.md:142:CR0085 should be reviewed/retired separately after CR0086 is established.\",\"HEAD:kb/changes/CR-2026-0087-HANDOFF.md:11:- retired VM170 application/control-plane state is removed.\",\"HEAD:kb/changes/CR-2026-0087-HANDOFF.md:12:- VM171 retired monitoring closure is complete.\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:10:- CMD-1137..1140: VM171 retired Kuma/Prometheus monitoring closure completed and read back.\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:11:- CMD-1141: VM170 retired application payload removed; VM170 itself remains KEEP/CRITICAL as Gitea/core-app host.\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:14:- CMD-1144: retired current registry/backup metadata, stale latest-state/runbooks and orphan Beszel/SOPS current state removed; service registry, dependency map, runbooks and local desired-state regenerated.\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:24:- `/root/homelab-cleanup-backups/CR-2026-0087/cmd-1139-retired-health`\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:26:- `/var/backups/homelab-cleanup/CR-2026-0087/cmd-1141-vm170-retired-payload`\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:29:- `/var/backups/homelab-cleanup/CR-2026-0087/cmd-1144-retired-current-state`\",\"HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:37:`tools/collect_context.py` no longer tracks the retired `homelab-crypto-portfolio-chart-health.timer`; generated context is refreshed from cleaned current state.\",\"HEAD:kb/current/01_CURRENT_STATE.md:12:- old Mailcow/old NetBird server architecture is retired from production; rollback window remains.\",\"HEAD:kb/current/04_P0_NEXT.md:5:3. Canonical post-migration CR including NetBird new USA, Postbox/Null MX, Moldova V3/Gotify, old-USA retirement window and dependencies.\",\"HEAD:kb/private/archive/2026-08-19/MANIFEST.tsv:18:docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md\\t1740\",\"HEAD:kb/private/archive/2026-08-19/MANIFEST.tsv:24:docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md\\t2504\",\"HEAD:kb/private/archive/2026-08-19/MANIFEST.tsv:29:docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md\\t963\",\"HEAD:kb/private/archive/2026-08-19/README_FIRST.md:21:6. `docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md`\",\"HEAD:kb/private/archive/2026-08-19/SHA256SUMS:18:ad3ea70345063e8a13608a83acb4d6a1118533eb6acab22929e0bf1ac20c06af docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md\",\"HEAD:kb/private/archive/2026-08-19/SHA256SUMS:24:c8c11e3c6b8b5d9e2509f975657194944edbc89e483da04f2413224b79084309 docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md\",\"HEAD:kb/private/archive/2026-08-19/SHA256SUMS:29:426a22a970150ff86adbd441a616481fbcedfc1cdb48c5a4976862d747cbcd43 docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md\",\"HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:122:VM180 and CT200 are retirement candidates only, not blind-delete authorization.\",\"HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:153:Inbound email deliberately retired.\",\"HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:256:`/root/retired-mailcow-backups/mailcow-final-offline-20260818T185112Z`\",\"HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:264:Old observer retirement backup:\",\"HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:265:`/root/retired-homelab-dr-observer-20260818T221046Z`\",\"HEAD:kb/private/archive/2026-08-19/docs/02_CLUSTER_TOPOLOGY_AND_INVENTORY.md:74:Known consumers prove these are not currently safe to retire blindly.\",\"HEAD:kb/private/archive/2026-08-19/docs/05_BACKUP_DR_AND_CLOUDS.md:49:Lifecycle = not configured\",\"HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:20:- current mirror policy: verify or formally retire mirror\",\"HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:33:- second independent copy of retired Mailcow archive\",\"HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:92:Retire only with fresh consumer proof:\",\"HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:101:### Retirement projects\",\"HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:1:# CRITICAL KEEP / RETIRE DECISIONS\",\"HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:3:This is a convenience matrix distilled from the historical handbook plus current state. A RETIRE label is not authorization to delete without fresh proof.\",\"HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:16:| VM180 cluster-admin | historical future RETIRE candidate | only after dependency/backup/monitoring cleanup |\",\"HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:18:| CT200 skladchik-mod | historical future RETIRE candidate | preserve required data/monitoring first |\",\"HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:24:| pve01 18788 | KEEP NOW | reader-v3, usage proof before retirement |\",\"HEAD:kb/private/archive/2026-08-19/docs/17_CLOUDRU_CURRENT.md:18:lifecycle: absent\",\"HEAD:kb/private/archive/2026-08-19/docs/18_P0_CLOSEOUT_MASTER_PLAN_2026-08-19.md:35:- old NetBird server retirement\",\"HEAD:kb/private/archive/2026-08-19/docs/18_P0_CLOSEOUT_MASTER_PLAN_2026-08-19.md:36:- Mailcow retirement\",\"HEAD:kb/private/archive/2026-08-19/docs/18_P0_CLOSEOUT_MASTER_PLAN_2026-08-19.md:42:- AlexHost retirement/rollback window\",\"HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:1:# MAILCOW RETIREMENT / POSTBOX / FORUMS \\u2014 CURRENT RECORD\",\"HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:8:18 containers before retirement.\",\"HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:30:## Retirement\",\"HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:53:`/root/retired-mailcow-backups/mailcow-final-offline-20260818T185112Z`\",\"HEAD:kb/private/archive/2026-08-19/docs/22_MOLDOVA_HEALTHCHECK_GOTIFY_2026-08-18.md:14:Old checker referenced retired Mailcow/old NetBird IP and caused false failures.\",\"HEAD:kb/private/archive/2026-08-19/docs/22_MOLDOVA_HEALTHCHECK_GOTIFY_2026-08-18.md:48:Old USA observer had been converted to Gotify-only before retirement.\",\"HEAD:kb/private/archive/2026-08-19/docs/22_MOLDOVA_HEALTHCHECK_GOTIFY_2026-08-18.md:103:`/root/retired-homelab-dr-observer-20260818T221046Z`\",\"HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:20:- current mirror policy: verify or formally retire mirror\",\"HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:33:- second independent copy of retired Mailcow archive\",\"HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:92:Retire only with fresh consumer proof:\",\"HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:101:### Retirement projects\",\"HEAD:kb/private/archive/2026-08-19/docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md:1:# ALEXHOST RETIREMENT / BILLING STATE \\u2014 2026-08-19\",\"HEAD:kb/private/archive/2026-08-19/docs/27_SECURITY_ACCESS_CURRENT_DELTA_2026-08-19.md:12:Lifecycle:\",\"HEAD:kb/private/archive/2026-08-19/docs/27_SECURITY_ACCESS_CURRENT_DELTA_2026-08-19.md:14:- after accepted old-USA shutdown/retirement:\",\"HEAD:kb/private/archive/2026-08-19/machine/current_state.json:108: \\\"lifecycle\\\": \\\"NOT_CONFIGURED\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/current_state.yaml:89: new_usa_path: \\\"/root/retired-mailcow-backups/mailcow-final-offline-20260818T185112Z\\\"\",\"HEAD:kb/private/source/source_manifest.json:83: \\\"path\\\": \\\"docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md\\\",\",\"HEAD:kb/private/source/source_manifest.json:98: \\\"path\\\": \\\"docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md\\\",\",\"HEAD:kb/private/source/source_manifest.json:113: \\\"path\\\": \\\"docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md\\\",\",\"HEAD:kb/runbooks/02_PROXMOX.md:12:Before deletion/retirement, prove consumers and backup/restore path. VM9130 remains protected until timed VM130 DR restore proof.\",\"HEAD:kb/runbooks/05_FORUMS_MAIL.md:9:Null MX means inbound mail is intentionally retired; do not \\u201crepair\\u201d old Mailcow MX/DNS as if outage without checking current policy.\",\"HEAD:kb/secrets/registry.json:92: \\\"lifecycle\\\": \\\"Remove after old-USA retirement accepted and corresponding authorized_keys line no longer needed.\\\"\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"fefced8de60a5efa9488a0bcc961ca0d75d90bc2f411e26a7fe40d4e0b106c78\"},\"current_vm200\":{\"lines\":[\"HEAD:kb/inventory/guests.json:136: \\\"name\\\": \\\"skladchik-mod\\\",\",\"HEAD:kb/inventory/guests.json:143: \\\"role\\\": \\\"skladchik-mod: moderator v2 + PostgreSQL\\\",\",\"HEAD:kb/private/archive/2026-08-19/docs/02_CLUSTER_TOPOLOGY_AND_INVENTORY.md:42:| 200 | skladchik-mod | lxc | pve03 | running | [PRIVATE_IP] | 6144 MiB | 39.1 GiB | skladchik-mod: moderator v2 + PostgreSQL |\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:230:## VM/LXC 200 \\u2014 skladchik-mod\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:232:Role: skladchik-mod: moderator v2 + PostgreSQL.\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:235:- `skladchik-moderator-v2-collector.service`\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:236:- `skladchik-moderator-v2-collector.timer`\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:237:- `skladchik-moderator-v2-rules.service`\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:238:- `skladchik-moderator-v2-rules.timer`\",\"HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:239:- `skladchik-moderator-v2-web.service`\",\"HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:18:| CT200 skladchik-mod | historical future RETIRE candidate | preserve required data/monitoring first |\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1929: \\\"name\\\": \\\"skladchik-mod\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1941: \\\"skladchik-moderator-v2-web.service\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1993: \\\"unit\\\": \\\"skladchik-moderator-v2-collector.timer\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1997: \\\"unit\\\": \\\"skladchik-moderator-v2-rules.timer\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2012: \\\"skladchik-moderator-v2-collector.service\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2013: \\\"skladchik-moderator-v2-collector.timer\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2014: \\\"skladchik-moderator-v2-rules.service\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2015: \\\"skladchik-moderator-v2-rules.timer\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2016: \\\"skladchik-moderator-v2-web.service\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2031: \\\"role\\\": \\\"skladchik-mod: moderator v2 + PostgreSQL\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2038: \\\"name\\\": \\\"skladchik-mod\\\",\",\"HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.tsv:13:200\\tskladchik-mod\\tlxc\\tpve03\\trunning\\t[PRIVATE_IP]\\t6144\\t39.1\\tskladchik-mod: moderator v2 + PostgreSQL\",\"HEAD:observed/cluster-guests.json:238: \\\"id\\\": \\\"lxc/200\\\",\",\"HEAD:observed/cluster-guests.json:244: \\\"name\\\": \\\"skladchik-mod\\\",\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"df20c2a29261d45b0b381d76e521bf77e9564403622c73fc1790fba39ba4d42d\"},\"head\":{\"lines\":[\"d5e2ef5639398a762283e47143c17b494f8ed579\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"baa4912ce1befe1c70ce681a7e9110152b3c894c8b36ed9880013efd7b70cb29\"},\"history\":{\"lines\":[],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"},\"refs\":{\"refs/heads/cr-2026-0035-skladchik-moderator-ct200\":{\"diff_names\":{\"lines\":[\"D\\t.gitea/workflows/validate-kb.yml\",\"M\\tACTIVE_CHANGES.md\",\"M\\tAGENTS.md\",\"M\\tCURRENT_CONTEXT.md\",\"D\\tKB_START_HERE.md\",\"M\\tREADME.md\",\"D\\tchanges/CR-2026-0018/acceptance.json\",\"D\\tchanges/CR-2026-0018/caller-inventory-requirements.md\",\"D\\tchanges/CR-2026-0018/design.md\",\"A\\tchanges/CR-2026-0018/evidence.md\",\"D\\tchanges/CR-2026-0018/execution-contract.md\",\"A\\tchanges/CR-2026-0018/plan.json\",\"D\\tchanges/CR-2026-0018/plan.md\",\"D\\tchanges/CR-2026-0018/regression-cases-draft.json\",\"D\\tchanges/CR-2026-0018/request.json\",\"D\\tchanges/CR-2026-0018/review-decision.md\",\"M\\tchanges/CR-2026-0018/risk.md\",\"M\\tchanges/CR-2026-0018/rollback.md\",\"A\\tchanges/CR-2026-0018/task-package.sha256\",\"D\\tchanges/CR-2026-0018/task-reference.md\",\"M\\tchanges/CR-2026-0018/tests.md\",\"D\\tchanges/CR-2026-0018/threat-model.md\",\"A\\tchanges/CR-2026-0019/evidence.md\",\"A\\tchanges/CR-2026-0019/plan.json\",\"A\\tchanges/CR-2026-0019/risk.md\",\"A\\tchanges/CR-2026-0019/rollback.md\",\"A\\tchanges/CR-2026-0019/source-freeze.sha256\",\"A\\tchanges/CR-2026-0019/task-package.sha256\",\"A\\tchanges/CR-2026-0019/tests.md\",\"A\\tchanges/CR-2026-0026/design-package.sha256\",\"A\\tchanges/CR-2026-0026/discovery.md\",\"A\\tchanges/CR-2026-0026/implementation.md\",\"A\\tchanges/CR-2026-0026/plan.json\",\"A\\tchanges/CR-2026-0026/risk.md\",\"A\\tchanges/CR-2026-0026/rollback.md\",\"A\\tchanges/CR-2026-0026/source-provenance.tsv\",\"A\\tchanges/CR-2026-0026/task-package.sha256\",\"A\\tchanges/CR-2026-0026/tests.md\",\"A\\tchanges/CR-2026-0027/design-package.sha256\",\"A\\tchanges/CR-2026-0027/discovery.md\",\"A\\tchanges/CR-2026-0027/implementation.md\",\"A\\tchanges/CR-2026-0027/plan.json\",\"A\\tchanges/CR-2026-0027/risk.md\",\"A\\tchanges/CR-2026-0027/rollback.md\",\"A\\tchanges/CR-2026-0027/source-provenance.tsv\",\"A\\tchanges/CR-2026-0027/task-package.sha256\",\"A\\tchanges/CR-2026-0027/tests.md\",\"A\\tchanges/CR-2026-0028/design-package.sha256\",\"A\\tchanges/CR-2026-0028/discovery.md\",\"A\\tchanges/CR-2026-0028/implementation.md\",\"A\\tchanges/CR-2026-0028/plan.json\",\"A\\tchanges/CR-2026-0028/risk.md\",\"A\\tchanges/CR-2026-0028/rollback.md\",\"A\\tchanges/CR-2026-0028/source-provenance.tsv\",\"A\\tchanges/CR-2026-0028/task-package.sha256\",\"A\\tchanges/CR-2026-0028/tests.md\",\"A\\tchanges/CR-2026-0029/design-package.sha256\",\"A\\tchanges/CR-2026-0029/discovery.md\",\"A\\tchanges/CR-2026-0029/implementation.md\",\"A\\tchanges/CR-2026-0029/plan.json\",\"A\\tchanges/CR-2026-0029/risk.md\",\"A\\tchanges/CR-2026-0029/rollback.md\",\"A\\tchanges/CR-2026-0029/source-provenance.tsv\",\"A\\tchanges/CR-2026-0029/task-package.sha256\",\"A\\tchanges/CR-2026-0029/tests.md\",\"A\\tchanges/CR-2026-0030/design-package.sha256\",\"A\\tchanges/CR-2026-0030/discovery.md\",\"A\\tchanges/CR-2026-0030/implementation.md\",\"A\\tchanges/CR-2026-0030/plan.json\",\"A\\tchanges/CR-2026-0030/risk.md\",\"A\\tchanges/CR-2026-0030/rollback.md\",\"A\\tchanges/CR-2026-0030/source-provenance.tsv\",\"A\\tchanges/CR-2026-0030/task-package.sha256\",\"A\\tchanges/CR-2026-0030/tests.md\",\"A\\tchanges/CR-2026-0031/design-package.sha256\",\"A\\tchanges/CR-2026-0031/discovery.md\",\"A\\tchanges/CR-2026-0031/implementation.md\",\"A\\tchanges/CR-2026-0031/risk.md\",\"A\\tchanges/CR-2026-0031/source-provenance.tsv\",\"A\\tchanges/CR-2026-0031/task-package.sha256\",\"A\\tchanges/CR-2026-0031/tests.md\",\"A\\tchanges/CR-2026-0032/README.md\",\"A\\tchanges/CR-2026-0032/design-package.sha256\",\"A\\tchanges/CR-2026-0032/task-package.sha256\",\"A\\tchanges/CR-2026-0033/README.md\",\"A\\tchanges/CR-2026-0033/design-package.sha256\",\"A\\tchanges/CR-2026-0033/task-package.sha256\",\"A\\tchanges/CR-2026-0034/README.md\",\"A\\tchanges/CR-2026-0034/design-package.sha256\",\"A\\tchanges/CR-2026-0034/task-package.sha256\",\"A\\tchanges/CR-2026-0035/discovery.md\",\"A\\tchanges/CR-2026-0035/implementation.md\",\"A\\tchanges/CR-2026-0035/package.sha256\",\"A\\tchanges/CR-2026-0035/risk.md\",\"A\\tchanges/CR-2026-0035/source-provenance.tsv\",\"A\\tchanges/CR-2026-0035/tests.md\",\"D\\tchanges/CR-2026-0078/task-package.sha256\",\"D\\tchanges/CR-2026-0079/README.md\",\"D\\tchanges/CR-2026-0079/mail-pvepro-dr-observer-source.tar.gz\",\"D\\tchanges/CR-2026-0079/task-package.sha256\",\"D\\tchanges/CR-2026-0080/task-package.sha256\",\"D\\tchanges/CR-2026-0081/home-forward-retire-package.sha256\",\"D\\tchanges/CR-2026-0081/turn-dns-retire-package.sha256\",\"D\\tchanges/CR-2026-0083/README.md\",\"D\\tchanges/CR-2026-0083/gitea-edge-publisher-v3-deploy-v1.tar.gz\",\"D\\tchanges/CR-2026-0083/gitea-edge-publisher-v3-source-v1.tar.gz\",\"D\\tchanges/CR-2026-0083/source-package.sha256\",\"D\\tdeploy/gitea-edge-publisher-v3/MANIFEST.sha256\",\"D\\tdeploy/gitea-edge-publisher-v3/deploy.sh\",\"D\\tdeploy/gitea-edge-publisher-v3/nginx/git-read-access-log-format.conf\",\"D\\tdeploy/gitea-edge-publisher-v3/nginx/git-read-server-observer.conf\",\"D\\tdeploy/gitea-edge-publisher-v3/patch_vhost.py\",\"D\\tdeploy/gitea-edge-publisher-v3/payload/homelab-gitea-publisher-v3\",\"D\\tdeploy/gitea-edge-publisher-v3/payload/homelab-oai-searchbot-observer\",\"D\\tdeploy/gitea-edge-publisher-v3/payload/homelab-oai-searchbot-ranges\",\"D\\tdeploy/gitea-edge-publisher-v3/rollback.sh\",\"D\\tdeploy/gitea-edge-publisher-v3/selftest.sh\",\"D\\tdeploy/gitea-edge-publisher-v3/systemd/homelab-gitea-publisher-v3.service\",\"D\\tdeploy/gitea-edge-publisher-v3/systemd/homelab-gitea-publisher-v3.timer\",\"D\\tdeploy/gitea-edge-publisher-v3/systemd/homelab-oai-searchbot-observer.service\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"9f24c0031ba6ccee22a76aee6935c5ff9da440b743eb9428ba38332195f1e1e5\"},\"exists\":true,\"vm200\":{\"lines\":[\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-freshness-probe:12: memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) printf 'app-%s\\\\n' \\\"$1\\\" ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-queue:9:ALL_APPS=(memos skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-queue:10:MIGRATE_APPS=(skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-queue:84: case \\\"$a\\\" in memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) ;; *) die \\\"APP_NOT_ALLOWED_$a\\\" 64 ;; esac\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:72: skladchik-moderator-assistant) echo app-skladchik-moderator-assistant ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:85: skladchik-moderator-assistant) echo pve01 ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:173: started=\\\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\\\"; new_capture_paths skladchik-moderator-assistant \\\"$gen\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:174: mkdir -p \\\"$CAPTURE/skladchik-moderator-assistant/var-lib\\\" \\\"$CAPTURE/skladchik-moderator-assistant/opt\\\" \\\"$CAPTURE/skladchik-moderator-assistant/systemd\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:175: [[ -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ]] || die MODERATOR_DB_MISSING 66\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:176: sqlite3 /var/lib/skladchik-moderator-assistant/state.sqlite3 \\\".backup '$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3'\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:177: chown --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:178: chmod --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:179: touch -r /var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:180: [[ \\\"$(sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\" 'PRAGMA integrity_check;'|tail -n1)\\\" == ok ]] || die MODERATOR_DB_BACKUP_INVALID 70\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:181: cp -a /opt/skladchik-moderator-assistant/. \\\"$CAPTURE/skladchik-moderator-assistant/opt/\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:182: [[ -f /etc/systemd/system/skladchik-moderator-assistant.service ]] && cp -a /etc/systemd/system/skladchik-moderator-assistant.service \\\"$CAPTURE/skladchik-moderator-assistant/systemd/\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:183: dbsha=\\\"$(sha256sum \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"|awk '{print $1}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:184: manifest_tree \\\"$CAPTURE/skladchik-moderator-assistant\\\" \\\"$CAPTURE/skladchik-moderator-assistant/files.sha256\\\"; treesha=\\\"$(sha256sum \\\"$CAPTURE/skladchik-moderator-assistant/files.sha256\\\"|awk '{print $1}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:186: comps=\\\"$(jq -n --arg a \\\"$dbsha\\\" --arg b \\\"$treesha\\\" '{database:{path:\\\"skladchik-moderator-assistant/var-lib/state.sqlite3\\\",sha256:$a},files_manifest:{path:\\\"skladchik-moderator-assistant/files.sha256\\\",sha256:$b}}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:187: write_binding \\\"$CAPTURE/app-generation.json\\\" app-skladchik-moderator-assistant \\\"$gen\\\" skladchik-moderator-assistant \\\"$started\\\" \\\"$completed\\\" \\\"\\\" \\\"\\\" \\\"$comps\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:358: skladchik-moderator-assistant) capture_moderator \\\"$gen\\\" ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:433: skladchik-moderator-assistant)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:434: db=\\\"$ex/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"; [[ \\\"$(sqlite3 \\\"$db\\\" 'PRAGMA integrity_check;'|tail -n1)\\\" == ok ]] || die MODERATOR_RESTORE_INTEGRITY_FAILED 70\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:436: (cd \\\"$ex/skladchik-moderator-assistant\\\"; sha256sum -c files.sha256 >/dev/null)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:437: find \\\"$ex/skladchik-moderator-assistant/opt\\\" -type f -name '*.py' -print0 | xargs -0 -r python3 -m py_compile\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:624: skladchik-moderator-assistant) test -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-freshness-probe:12: memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) printf 'app-%s\\\\n' \\\"$1\\\" ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-queue:9:ALL_APPS=(memos skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-queue:10:MIGRATE_APPS=(skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-queue:84: case \\\"$a\\\" in memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) ;; *) die \\\"APP_NOT_ALLOWED_$a\\\" 64 ;; esac\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:72: skladchik-moderator-assistant) echo app-skladchik-moderator-assistant ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:85: skladchik-moderator-assistant) echo pve01 ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:173: started=\\\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\\\"; new_capture_paths skladchik-moderator-assistant \\\"$gen\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:174: mkdir -p \\\"$CAPTURE/skladchik-moderator-assistant/var-lib\\\" \\\"$CAPTURE/skladchik-moderator-assistant/opt\\\" \\\"$CAPTURE/skladchik-moderator-assistant/systemd\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:175: [[ -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ]] || die MODERATOR_DB_MISSING 66\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:176: sqlite3 /var/lib/skladchik-moderator-assistant/state.sqlite3 \\\".backup '$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3'\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:177: chown --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:178: chmod --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:179: touch -r /var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:180: [[ \\\"$(sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\" 'PRAGMA integrity_check;'|tail -n1)\\\" == ok ]] || die MODERATOR_DB_BACKUP_INVALID 70\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:181: cp -a /opt/skladchik-moderator-assistant/. \\\"$CAPTURE/skladchik-moderator-assistant/opt/\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:182: [[ -f /etc/systemd/system/skladchik-moderator-assistant.service ]] && cp -a /etc/systemd/system/skladchik-moderator-assistant.service \\\"$CAPTURE/skladchik-moderator-assistant/systemd/\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:183: dbsha=\\\"$(sha256sum \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"|awk '{print $1}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:184: manifest_tree \\\"$CAPTURE/skladchik-moderator-assistant\\\" \\\"$CAPTURE/skladchik-moderator-assistant/files.sha256\\\"; treesha=\\\"$(sha256sum \\\"$CAPTURE/skladchik-moderator-assistant/files.sha256\\\"|awk '{print $1}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:186: comps=\\\"$(jq -n --arg a \\\"$dbsha\\\" --arg b \\\"$treesha\\\" '{database:{path:\\\"skladchik-moderator-assistant/var-lib/state.sqlite3\\\",sha256:$a},files_manifest:{path:\\\"skladchik-moderator-assistant/files.sha256\\\",sha256:$b}}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:187: write_binding \\\"$CAPTURE/app-generation.json\\\" app-skladchik-moderator-assistant \\\"$gen\\\" skladchik-moderator-assistant \\\"$started\\\" \\\"$completed\\\" \\\"\\\" \\\"\\\" \\\"$comps\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:358: skladchik-moderator-assistant) capture_moderator \\\"$gen\\\" ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:433: skladchik-moderator-assistant)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:434: db=\\\"$ex/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"; [[ \\\"$(sqlite3 \\\"$db\\\" 'PRAGMA integrity_check;'|tail -n1)\\\" == ok ]] || die MODERATOR_RESTORE_INTEGRITY_FAILED 70\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:436: (cd \\\"$ex/skladchik-moderator-assistant\\\"; sha256sum -c files.sha256 >/dev/null)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:437: find \\\"$ex/skladchik-moderator-assistant/opt\\\" -type f -name '*.py' -print0 | xargs -0 -r python3 -m py_compile\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:624: skladchik-moderator-assistant) test -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-freshness-probe:12: memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) printf 'app-%s\\\\n' \\\"$1\\\" ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-queue:9:ALL_APPS=(memos skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-queue:10:MIGRATE_APPS=(skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-queue:84: case \\\"$a\\\" in memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) ;; *) die \\\"APP_NOT_ALLOWED_$a\\\" 64 ;; esac\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:72: skladchik-moderator-assistant) echo app-skladchik-moderator-assistant ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:85: skladchik-moderator-assistant) echo pve01 ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:173: started=\\\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\\\"; new_capture_paths skladchik-moderator-assistant \\\"$gen\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:174: mkdir -p \\\"$CAPTURE/skladchik-moderator-assistant/var-lib\\\" \\\"$CAPTURE/skladchik-moderator-assistant/opt\\\" \\\"$CAPTURE/skladchik-moderator-assistant/systemd\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:175: [[ -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ]] || die MODERATOR_DB_MISSING 66\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:176: sqlite3 /var/lib/skladchik-moderator-assistant/state.sqlite3 \\\".backup '$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3'\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:177: chown --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:178: chmod --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:179: touch -r /var/lib/skladchik-moderator-assistant/state.sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:180: [[ \\\"$(sqlite3 \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\" 'PRAGMA integrity_check;'|tail -n1)\\\" == ok ]] || die MODERATOR_DB_BACKUP_INVALID 70\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:181: cp -a /opt/skladchik-moderator-assistant/. \\\"$CAPTURE/skladchik-moderator-assistant/opt/\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:182: [[ -f /etc/systemd/system/skladchik-moderator-assistant.service ]] && cp -a /etc/systemd/system/skladchik-moderator-assistant.service \\\"$CAPTURE/skladchik-moderator-assistant/systemd/\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:183: dbsha=\\\"$(sha256sum \\\"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"|awk '{print $1}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:184: manifest_tree \\\"$CAPTURE/skladchik-moderator-assistant\\\" \\\"$CAPTURE/skladchik-moderator-assistant/files.sha256\\\"; treesha=\\\"$(sha256sum \\\"$CAPTURE/skladchik-moderator-assistant/files.sha256\\\"|awk '{print $1}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:186: comps=\\\"$(jq -n --arg a \\\"$dbsha\\\" --arg b \\\"$treesha\\\" '{database:{path:\\\"skladchik-moderator-assistant/var-lib/state.sqlite3\\\",sha256:$a},files_manifest:{path:\\\"skladchik-moderator-assistant/files.sha256\\\",sha256:$b}}')\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:187: write_binding \\\"$CAPTURE/app-generation.json\\\" app-skladchik-moderator-assistant \\\"$gen\\\" skladchik-moderator-assistant \\\"$started\\\" \\\"$completed\\\" \\\"\\\" \\\"\\\" \\\"$comps\\\"\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:358: skladchik-moderator-assistant) capture_moderator \\\"$gen\\\" ;;\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:433: skladchik-moderator-assistant)\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:434: db=\\\"$ex/skladchik-moderator-assistant/var-lib/state.sqlite3\\\"; [[ \\\"$(sqlite3 \\\"$db\\\" 'PRAGMA integrity_check;'|tail -n1)\\\" == ok ]] || die MODERATOR_RESTORE_INTEGRITY_FAILED 70\",\"refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:436: (cd \\\"$ex/skladchik-moderator-assistant\\\"; sha256sum -c files.sha256 >/dev/null)\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"68d1d931e6d4c48dd15ac5faeb8feddb0548018245d16997d7c486f29c56d355\"}},\"refs/heads/cr-2026-0058-legacy-backup-target-retirement\":{\"diff_names\":{\"lines\":[\"D\\t.gitea/workflows/validate-kb.yml\",\"M\\tACTIVE_CHANGES.md\",\"M\\tAGENTS.md\",\"M\\tCURRENT_CONTEXT.md\",\"D\\tKB_START_HERE.md\",\"M\\tREADME.md\",\"D\\tchanges/CR-2026-0018/acceptance.json\",\"D\\tchanges/CR-2026-0018/caller-inventory-requirements.md\",\"D\\tchanges/CR-2026-0018/design.md\",\"A\\tchanges/CR-2026-0018/evidence.md\",\"D\\tchanges/CR-2026-0018/execution-contract.md\",\"A\\tchanges/CR-2026-0018/plan.json\",\"D\\tchanges/CR-2026-0018/plan.md\",\"D\\tchanges/CR-2026-0018/regression-cases-draft.json\",\"D\\tchanges/CR-2026-0018/request.json\",\"D\\tchanges/CR-2026-0018/review-decision.md\",\"M\\tchanges/CR-2026-0018/risk.md\",\"M\\tchanges/CR-2026-0018/rollback.md\",\"A\\tchanges/CR-2026-0018/task-package.sha256\",\"D\\tchanges/CR-2026-0018/task-reference.md\",\"M\\tchanges/CR-2026-0018/tests.md\",\"D\\tchanges/CR-2026-0018/threat-model.md\",\"A\\tchanges/CR-2026-0019/evidence.md\",\"A\\tchanges/CR-2026-0019/plan.json\",\"A\\tchanges/CR-2026-0019/risk.md\",\"A\\tchanges/CR-2026-0019/rollback.md\",\"A\\tchanges/CR-2026-0019/source-freeze.sha256\",\"A\\tchanges/CR-2026-0019/task-package.sha256\",\"A\\tchanges/CR-2026-0019/tests.md\",\"A\\tchanges/CR-2026-0026/design-package.sha256\",\"A\\tchanges/CR-2026-0026/discovery.md\",\"A\\tchanges/CR-2026-0026/implementation.md\",\"A\\tchanges/CR-2026-0026/plan.json\",\"A\\tchanges/CR-2026-0026/risk.md\",\"A\\tchanges/CR-2026-0026/rollback.md\",\"A\\tchanges/CR-2026-0026/source-provenance.tsv\",\"A\\tchanges/CR-2026-0026/task-package.sha256\",\"A\\tchanges/CR-2026-0026/tests.md\",\"A\\tchanges/CR-2026-0027/design-package.sha256\",\"A\\tchanges/CR-2026-0027/discovery.md\",\"A\\tchanges/CR-2026-0027/implementation.md\",\"A\\tchanges/CR-2026-0027/plan.json\",\"A\\tchanges/CR-2026-0027/risk.md\",\"A\\tchanges/CR-2026-0027/rollback.md\",\"A\\tchanges/CR-2026-0027/source-provenance.tsv\",\"A\\tchanges/CR-2026-0027/task-package.sha256\",\"A\\tchanges/CR-2026-0027/tests.md\",\"A\\tchanges/CR-2026-0028/design-package.sha256\",\"A\\tchanges/CR-2026-0028/discovery.md\",\"A\\tchanges/CR-2026-0028/implementation.md\",\"A\\tchanges/CR-2026-0028/plan.json\",\"A\\tchanges/CR-2026-0028/risk.md\",\"A\\tchanges/CR-2026-0028/rollback.md\",\"A\\tchanges/CR-2026-0028/source-provenance.tsv\",\"A\\tchanges/CR-2026-0028/task-package.sha256\",\"A\\tchanges/CR-2026-0028/tests.md\",\"A\\tchanges/CR-2026-0029/design-package.sha256\",\"A\\tchanges/CR-2026-0029/discovery.md\",\"A\\tchanges/CR-2026-0029/implementation.md\",\"A\\tchanges/CR-2026-0029/plan.json\",\"A\\tchanges/CR-2026-0029/risk.md\",\"A\\tchanges/CR-2026-0029/rollback.md\",\"A\\tchanges/CR-2026-0029/source-provenance.tsv\",\"A\\tchanges/CR-2026-0029/task-package.sha256\",\"A\\tchanges/CR-2026-0029/tests.md\",\"A\\tchanges/CR-2026-0030/design-package.sha256\",\"A\\tchanges/CR-2026-0030/discovery.md\",\"A\\tchanges/CR-2026-0030/implementation.md\",\"A\\tchanges/CR-2026-0030/plan.json\",\"A\\tchanges/CR-2026-0030/risk.md\",\"A\\tchanges/CR-2026-0030/rollback.md\",\"A\\tchanges/CR-2026-0030/source-provenance.tsv\",\"A\\tchanges/CR-2026-0030/task-package.sha256\",\"A\\tchanges/CR-2026-0030/tests.md\",\"A\\tchanges/CR-2026-0031/design-package.sha256\",\"A\\tchanges/CR-2026-0031/discovery.md\",\"A\\tchanges/CR-2026-0031/implementation.md\",\"A\\tchanges/CR-2026-0031/risk.md\",\"A\\tchanges/CR-2026-0031/source-provenance.tsv\",\"A\\tchanges/CR-2026-0031/task-package.sha256\",\"A\\tchanges/CR-2026-0031/tests.md\",\"A\\tchanges/CR-2026-0032/README.md\",\"A\\tchanges/CR-2026-0032/design-package.sha256\",\"A\\tchanges/CR-2026-0032/task-package.sha256\",\"A\\tchanges/CR-2026-0033/README.md\",\"A\\tchanges/CR-2026-0033/design-package.sha256\",\"A\\tchanges/CR-2026-0033/task-package.sha256\",\"A\\tchanges/CR-2026-0034/README.md\",\"A\\tchanges/CR-2026-0034/design-package.sha256\",\"A\\tchanges/CR-2026-0034/task-package.sha256\",\"A\\tchanges/CR-2026-0035/discovery.md\",\"A\\tchanges/CR-2026-0035/implementation.md\",\"A\\tchanges/CR-2026-0035/package.sha256\",\"A\\tchanges/CR-2026-0035/risk.md\",\"A\\tchanges/CR-2026-0035/source-provenance.tsv\",\"A\\tchanges/CR-2026-0035/tests.md\",\"A\\tchanges/CR-2026-0036/discovery.md\",\"A\\tchanges/CR-2026-0036/implementation.md\",\"A\\tchanges/CR-2026-0036/package.sha256\",\"A\\tchanges/CR-2026-0036/risk.md\",\"A\\tchanges/CR-2026-0036/source-provenance.tsv\",\"A\\tchanges/CR-2026-0036/tests.md\",\"A\\tchanges/CR-2026-0046/discovery.md\",\"A\\tchanges/CR-2026-0046/implementation.md\",\"A\\tchanges/CR-2026-0046/risk.md\",\"A\\tchanges/CR-2026-0046/source-provenance.tsv\",\"A\\tchanges/CR-2026-0046/task-package.sha256\",\"A\\tchanges/CR-2026-0046/tests.md\",\"A\\tchanges/CR-2026-0047/task-package.sha256\",\"A\\tchanges/CR-2026-0048/discovery.md\",\"A\\tchanges/CR-2026-0048/implementation.md\",\"A\\tchanges/CR-2026-0048/risk.md\",\"A\\tchanges/CR-2026-0048/source-provenance.tsv\",\"A\\tchanges/CR-2026-0048/task-package.sha256\",\"A\\tchanges/CR-2026-0048/tests.md\",\"A\\tchanges/CR-2026-0049/discovery.md\",\"A\\tchanges/CR-2026-0049/implementation.md\",\"A\\tchanges/CR-2026-0049/risk.md\",\"A\\tchanges/CR-2026-0049/source-provenance.tsv\",\"A\\tchanges/CR-2026-0049/task-package.sha256\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"40ecc0852c5589b22a435e26bbcf5702ae59069739901be6f22734bf008538f1\"},\"exists\":true,\"vm200\":{\"lines\":[\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:12:- Recovery after the initial external-network timeout uses a dedicated `skladchik-moderator-v2-edge-egress-v1` task: CT200 alone uses edge-vm `[PRIVATE_IP]` as its default gateway; edge-vm NATs only `[PRIVATE_IP]/32` into its already-existing NetBird `wt0` default exit (table 7120). No NetBird management policy is changed.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:26:Authenticated section evidence on 2026-08-12 showed 107 `discussionListItem` nodes, 106 `PreviewTooltip` markers and 517 root-relative `threads/...` hrefs. `skladchik-moderator-v2-xf1-parser-hotfix-v1` overlays only `forum.py` and `ads.py`, preserving XF2 support while adding XF1 listing/topic/message/search parsing and root-relative URL resolution. Cookie onboarding is fail-closed on the parser hotfix seal and exact installed module SHA values.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:42:The first controlled cookie apply proved the edge-vm source jar before mutation, installed it, then failed only at the v2 `auth-check`; the apply error path removed the CT200 cookie, disabled collector/competitor timers, and removed transient pve03 staging. The divergence was between two authentication classifiers: edge-vm proves the moderator session by authenticated XenForo 1 `discussionListItem` rows, while v2 still downgraded the same cookie-backed section using a text-only login heuristic. `skladchik-moderator-v2-auth-classification-hotfix-v1` preserves the sealed XF1 parser and changes only section authentication classification: a cookie-backed section that parses canonical topic rows is positive auth evidence. This is bounded by the already-observed public response yielding zero rows \",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:54:The authenticated bootstrap reached 104 listed topics and 40 detailed topics but produced zero analyses because every analyzed detail failed at `stage_history.stage = %s` with PostgreSQL `text = bytea`. The application connection inherited `SQL_ASCII`, so Psycopg returned text values as Python bytes and adapted the fetched stage back as `bytea` on the next parameterized query. The fix is at the connection boundary, not an SQL cast: `skladchik-moderator-v2-db-text-encoding-hotfix-v1` pins Psycopg `client_encoding=UTF8`, proves the baseline bytes failure against existing data, then performs a pre-mutation UTF8 probe across every existing app-facing text column and the exact formerly failing stage-history query; apply/verify repeat that proof through the installed module. No schema or data rewr\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:58:The post-cookie health failure after successful authenticated collection (104 listed topics, 17 analyses in the triggering run; 65 analyses persisted overall) was isolated to rule state. The formatting-rule fetch inherited the moderator cookie and was redirected to XenForo `/login/two-step`, creating a non-approved rule-source revision. Rule pages are public policy sources, so `skladchik-moderator-v2-rules-public-sync-hotfix-v1` fetches them through an independent cookie-free Requests session and requires the redirected final URL to preserve the expected rule thread id. Before mutation, the live dry-run requires each current public content hash to already exist as an explicitly approved historical source; a genuinely new rule revision therefore still stops for manual review and is never auto\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:62:The final cookie bootstrap exposed a collector-only SQL defect after all 104 section topics had already been detailed: `global_search_hits` used `ON CONFLICT DO UPDATE` without the unique-key inference target, so PostgreSQL rejected every whole-site duplicate-search upsert for the remaining four topics. Because detail state is committed before duplicate search and analysis, those topics then became ineligible for another detail fetch for two days. `skladchik-moderator-v2-collector-resume-hotfix-v1` fixes the upsert against the existing `UNIQUE(source_topic_id,query_kind,query_text,hit_url)` key and adds a cached-detail analysis backlog that retries topics whose latest committed detail has no analysis at or after that detail timestamp. Its dry-run executes the corrected upsert twice inside a \",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:70:After cookie onboarding is SEALED and current v2 health/timers are re-proven, `skladchik-moderator-v2-old-mvp-retirement-v1` retires only the legacy pve01 operational service. The task pins the exact legacy unit/app/rules bytes and version, captures root-only rollback copies, disables/stops the service, removes `/etc/systemd/system/skladchik-moderator-assistant.service` and `/opt/skladchik-moderator-assistant`, and preserves `/var/lib/skladchik-moderator-assistant` unchanged as inert historical state. Any apply/verify failure before seal restores the exact legacy unit/application and service state. Retirement does not touch CT200, complaints, forum state, or v2 data.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:74:The final retirement task does not delete `/opt/skladchik-moderator-assistant`. The existing app-cloud backup scheduler still schedules `skladchik-moderator-assistant`, and its worker captures `/var/lib/skladchik-moderator-assistant/state.sqlite3` plus `/opt/skladchik-moderator-assistant`. Deleting the legacy app directory would therefore break the next scheduled app backup. Retirement is corrected to disable/stop the old service and remove only its systemd unit/endpoint while preserving the exact legacy app and StateDirectory as inert, byte-pinned historical payload. The task read-only proves the existing queue/audit/worker backup contract before and after retirement; backup runtime itself is not modified.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:76:The old MVP unit uses `DynamicUser=yes` with `StateDirectory=skladchik-moderator-assistant`. Retirement accepts the normal directory layout or the exact systemd-managed `/var/lib/skladchik-moderator-assistant` symlink resolving to `/var/lib/private/skladchik-moderator-assistant`; the SQLite file itself must remain a regular non-symlink file.\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:6:4e119cef286d48ac4675235a82309e0c1087316bcada25bc6f8f43aea665e1dd tasks/skladchik-moderator-v2-application-v1/assets/app-payload.tar.gz\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:7:cf37824d4bb8d0d412d505cfeca33c81ddc37ac31ceedb6b131181653895fad1 tasks/skladchik-moderator-v2-application-v1/assets/app/config.json\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:8:761de78bd15049d408ed2f109a0fcd87e453d702defdf0e8d1547e1b35a55974 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/__init__.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:9:3e90e6c148a2b7ba52072be35280130f00fb966cfb94b76908fbd2eecd965b35 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/ads.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:10:5664ff8e9d45381a0c08a71a794060e60db8f523bd32911b390d28014066fc6c tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/analyzer.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:11:56f52f89fff1468d5e13da29c3c10cf60bc0aea06d71be871dcfc805aec23b60 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/cli.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:12:122e44d95edfc1c205cdee589ab83a9ccbce724a7951b569995e29171d4cb393 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/collector.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:13:0fd4e356a70e56f7293492b5f3d7677cc1a31156ba1964b3997c8852483edf63 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/competitors.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:14:bb207fe35de98aae0013a15eb27294e24902beeda01daf4f9b404bd8600165bc tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/config.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:15:ba63cc5d4f4e68a0cdd82c985d4fd5989fe9cf4c3beefb94ef1643d4a83bb80e tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/db.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:16:9e3bfd6a9481768800897f4a6be27e68f27e10bec96d3dda567407443b03bc99 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/forum.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:17:5b61133d9b2a72a8e5b86c01627899f60c988dee52fc7fdcc7adb7f82ebe1d47 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/normalize.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:18:88b5d4874b865ebe82ece25448a55bd083f4fb95a2c203621d715b6f0f58df57 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/rules.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:19:4c400f907b0c8fd57a4959a2d3fbc83206fd577e4429b7947e372f15c1637c25 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/schema.sql\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:20:6710a6dae5c3889412c823af20a989d2f1f072dd03451c9b1e00b6078aab570d tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/webapp.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:21:3d7e4c0054a958c6f440ffc2ee112360e1d7a433d3371590deb7575f89323f3b tasks/skladchik-moderator-v2-application-v1/assets/app/wsgi.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:22:f2f353dd56327395e03d26942deadf4987ac9b3a8a244dc87b3bddbbf9a301d9 tasks/skladchik-moderator-v2-application-v1/assets/pve03-app.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:23:04a441d36e41d30e1190dab7e71d3c05fb5733248ee7308f9b1b675abbf414b9 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.service\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:24:fee9af8ac8ab3f875a2860178b1029a1bc2fa251bf6e42a021585e02eee90c17 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.timer\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:25:d9e99cb8f07c328842f1eebc6d262dca623173cb9cfdd7e2afb4b279449a9519 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.service\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:26:37cd7bfe11a6c1cd70d5da7c62af19d7147e5f70a9641a0641cac8acbc709bb2 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.timer\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:27:9789f77fc9d6e246cacbc915b178ed2fedcf1367f7af8fe20a98881abe6597c5 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.service\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:28:a56c7d0c1bef8917f2407cabc9e27d0461b19f5af2698e556365d00673a93180 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.timer\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:29:e9cb92c0702ae26a0c6a063ffaaab0f1bafc08a82c05263509e112ff7847edae tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-web.service\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:30:6e7e7f45c756bec56a64321ebb6ca89d8f4edb8e070a57481e730e2c876deeeb tasks/skladchik-moderator-v2-application-v1/phases/apply.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:31:d17e4d6f9e9eece7672bccd18dec0fb533810fafb469e0e2ca99753fa5fe4136 tasks/skladchik-moderator-v2-application-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:32:8a39aef9926a6cf55c659937817bc5dc12657d5ef1f7edd549dc99530b88ade9 tasks/skladchik-moderator-v2-application-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:33:5157ec8da4bcfc0b88ccac54bed52a3ffeb676d5513cdb3f6b4ed5955658f76a tasks/skladchik-moderator-v2-application-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:34:403263caebb4925ada3957e0dbc852cf1813ba4ceda3fb308c33b2b22107c955 tasks/skladchik-moderator-v2-application-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:35:11f128d5da0a7c1276b77e10400e825a267633828cd173c0d8e5582902d28443 tasks/skladchik-moderator-v2-application-v1/phases/seal.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:36:3fba9b905dccf09dff024684894443d3b670b973f67c9db7653efde0b1c42fe8 tasks/skladchik-moderator-v2-application-v1/phases/verify.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:37:b9b2aa5fa48836fecbec286136377b8d6af00383df9e1a97b5ba0833c4099d27 tasks/skladchik-moderator-v2-application-v1/task.json\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:38:4b4c8d38c0e6613ec6cf2c6aaf873c506fffe5fd400566255e2a77618da7bb90 tasks/skladchik-moderator-v2-application-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:39:0c23274ab9b0ea843595689536284c86bdc7746220ebb4f140ccd1fff2c752bd tasks/skladchik-moderator-v2-application-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:40:6f9b3c541c451c4b9c0d2d394931c1b7e868349bef3e53167160298df703f2f6 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/auth-selftest.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:41:25eaabbddc54235aaafd2f5829c7e8ed9d1defcf76b8327cf347aeefda823ae0 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/forum.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:42:c2cccab25c73ec554d1a51f9dccf32343b50f5ff3efc4d65c55361032f1a2c30 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/pve03-auth-classifier.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:43:5f6e75e0b38671c55129e2975c64ab8522197f997dae370e3f513628452f1783 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/apply.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:44:caec61da54d9c40bd7cfed623617002c06a18e9604195b6057eb9e4e9bbee294 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:45:92ee9f19e3a83c1c244c033a277ed5ad312bd7396fd2b3fb9bdd4047aa847957 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:46:7c1ba5eb1e973ac5a2dd1651c89a05ba5a133f5bcf59ec216395887f9019ed7b tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:47:1c95a608369828b9da7c5d78fe630b5b4d947a799cbd22006a02be85686d5d75 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:48:2ab9124cc1428a68ca55c86fe6184f9fce8885dc353218a2caa2d8af742f0c89 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/seal.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:49:06e4185e2678a7e8a71514dd41b1845e84b1099f98003e234929aaa23d1c5d4a tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/verify.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:50:40ed940ba18618988294feede2a24d825a95c8a9ba84d5491f46664466be6b2e tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/task.json\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:51:3d0827c41d83923e0672d2d07f0502f42abc55b825f2f5e5c42dafa851c69419 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:52:49c5c42d757ee1e37123a5dc945d2a17631b74c394dbcd621e90ed7ad132cc72 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:53:011936d623941792240f8687443220e81357b68b17d419ebcdaa721d0473c63b tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/edge-cookie-source.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:54:56a9ab7d9169987c3b8fae6de29e6a3adb4538e34664d1b77c8c6203a9003474 tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/pve03-cookie.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:55:fb70f92b602588b73eb7eec5816387669576b5de2e07b69ff90de328bef3026b tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/apply.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:56:1ed1ad4b17f96dee387b23989b3e3a974ed501cd5d694cade4d085d52dd295a1 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:57:a839dd24e8b7c786b3130bd716841e0ced43c49ea1ab3314aebbeaca07dfd436 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:58:e377d14af824721cc1986889f1291da70b87901d1837769390d378f4d2fe5e13 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:59:014cf33ef917d193385449fc13201cefa84148608eb4fd6d3e5f30be06d1dd73 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:60:268b03a7b39225bfb2c97c4c87827c819e2ed727138b6158ff976469daf6887a tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/seal.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:61:6dafb047863c6df90898beeb99dd5ef04862afae3b8a3af57eb8290c671434a6 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/verify.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:62:feec58b4018f777a212520a795e7605455c6fb41da7a1792b60e1d57981c4689 tasks/skladchik-moderator-v2-cookie-onboarding-v1/task.json\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:63:4a8ae4ac4d749a4a7d10b8a21d2729dc2242ef4b0cd3b06f28ac89dd2bbff92c tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:64:93cb00411e45d9bdd9cb035869fe2be230f6147e76a8898a36606c51d9bcb568 tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:65:2ee3682cb57e7b6d04195a37b8f7acafde5cb2dc9ca28820e25c7143b3db4706 tasks/skladchik-moderator-v2-edge-egress-v1/assets/edge-egress.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:66:207793e2fa360abb88d535912d7d013af8bc822f4ffb1d8f55a3ea0967dc1ad6 tasks/skladchik-moderator-v2-edge-egress-v1/assets/pve03-egress.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:67:3c32c482e3232df8a2c4d25f553e8e7198c33a378e0600f53c01f71d14d9b3f6 tasks/skladchik-moderator-v2-edge-egress-v1/phases/apply.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:68:c51e41420b857f7d0ff2b8a16c8d0a339b4b942020d4ae59f80721e113e37eec tasks/skladchik-moderator-v2-edge-egress-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:69:d5e83720f2d842f4a1a2aba7ae4a55ce5494d16a43aa67f280d21c3cbed74d16 tasks/skladchik-moderator-v2-edge-egress-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:70:ee7ba739521639244e37ecf63d218bc18202701e53970f46eb987f7f3c6cb3b5 tasks/skladchik-moderator-v2-edge-egress-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:71:23aa44a61d9a6197ef236cc71b3f5eb4f9c38cdb24ae68eaa52113d34ac96ac0 tasks/skladchik-moderator-v2-edge-egress-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:72:ef7485307bd7e9b49c9102268db8b729049226f631441362ad3c2c5227516c12 tasks/skladchik-moderator-v2-edge-egress-v1/phases/seal.sh\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"b13094744d9f29c47fc973085e76f2db0645d2b5259d8f98bac8280c34c906c8\"}},\"refs/heads/cr-2026-0066-legacy-backup-target-retirement\":{\"diff_names\":{\"lines\":[\"D\\t.gitea/workflows/validate-kb.yml\",\"M\\tACTIVE_CHANGES.md\",\"M\\tAGENTS.md\",\"M\\tCURRENT_CONTEXT.md\",\"D\\tKB_START_HERE.md\",\"M\\tREADME.md\",\"D\\tchanges/CR-2026-0018/acceptance.json\",\"D\\tchanges/CR-2026-0018/caller-inventory-requirements.md\",\"D\\tchanges/CR-2026-0018/design.md\",\"A\\tchanges/CR-2026-0018/evidence.md\",\"D\\tchanges/CR-2026-0018/execution-contract.md\",\"A\\tchanges/CR-2026-0018/plan.json\",\"D\\tchanges/CR-2026-0018/plan.md\",\"D\\tchanges/CR-2026-0018/regression-cases-draft.json\",\"D\\tchanges/CR-2026-0018/request.json\",\"D\\tchanges/CR-2026-0018/review-decision.md\",\"M\\tchanges/CR-2026-0018/risk.md\",\"M\\tchanges/CR-2026-0018/rollback.md\",\"A\\tchanges/CR-2026-0018/task-package.sha256\",\"D\\tchanges/CR-2026-0018/task-reference.md\",\"M\\tchanges/CR-2026-0018/tests.md\",\"D\\tchanges/CR-2026-0018/threat-model.md\",\"A\\tchanges/CR-2026-0019/evidence.md\",\"A\\tchanges/CR-2026-0019/plan.json\",\"A\\tchanges/CR-2026-0019/risk.md\",\"A\\tchanges/CR-2026-0019/rollback.md\",\"A\\tchanges/CR-2026-0019/source-freeze.sha256\",\"A\\tchanges/CR-2026-0019/task-package.sha256\",\"A\\tchanges/CR-2026-0019/tests.md\",\"A\\tchanges/CR-2026-0026/design-package.sha256\",\"A\\tchanges/CR-2026-0026/discovery.md\",\"A\\tchanges/CR-2026-0026/implementation.md\",\"A\\tchanges/CR-2026-0026/plan.json\",\"A\\tchanges/CR-2026-0026/risk.md\",\"A\\tchanges/CR-2026-0026/rollback.md\",\"A\\tchanges/CR-2026-0026/source-provenance.tsv\",\"A\\tchanges/CR-2026-0026/task-package.sha256\",\"A\\tchanges/CR-2026-0026/tests.md\",\"A\\tchanges/CR-2026-0027/design-package.sha256\",\"A\\tchanges/CR-2026-0027/discovery.md\",\"A\\tchanges/CR-2026-0027/implementation.md\",\"A\\tchanges/CR-2026-0027/plan.json\",\"A\\tchanges/CR-2026-0027/risk.md\",\"A\\tchanges/CR-2026-0027/rollback.md\",\"A\\tchanges/CR-2026-0027/source-provenance.tsv\",\"A\\tchanges/CR-2026-0027/task-package.sha256\",\"A\\tchanges/CR-2026-0027/tests.md\",\"A\\tchanges/CR-2026-0028/design-package.sha256\",\"A\\tchanges/CR-2026-0028/discovery.md\",\"A\\tchanges/CR-2026-0028/implementation.md\",\"A\\tchanges/CR-2026-0028/plan.json\",\"A\\tchanges/CR-2026-0028/risk.md\",\"A\\tchanges/CR-2026-0028/rollback.md\",\"A\\tchanges/CR-2026-0028/source-provenance.tsv\",\"A\\tchanges/CR-2026-0028/task-package.sha256\",\"A\\tchanges/CR-2026-0028/tests.md\",\"A\\tchanges/CR-2026-0029/design-package.sha256\",\"A\\tchanges/CR-2026-0029/discovery.md\",\"A\\tchanges/CR-2026-0029/implementation.md\",\"A\\tchanges/CR-2026-0029/plan.json\",\"A\\tchanges/CR-2026-0029/risk.md\",\"A\\tchanges/CR-2026-0029/rollback.md\",\"A\\tchanges/CR-2026-0029/source-provenance.tsv\",\"A\\tchanges/CR-2026-0029/task-package.sha256\",\"A\\tchanges/CR-2026-0029/tests.md\",\"A\\tchanges/CR-2026-0030/design-package.sha256\",\"A\\tchanges/CR-2026-0030/discovery.md\",\"A\\tchanges/CR-2026-0030/implementation.md\",\"A\\tchanges/CR-2026-0030/plan.json\",\"A\\tchanges/CR-2026-0030/risk.md\",\"A\\tchanges/CR-2026-0030/rollback.md\",\"A\\tchanges/CR-2026-0030/source-provenance.tsv\",\"A\\tchanges/CR-2026-0030/task-package.sha256\",\"A\\tchanges/CR-2026-0030/tests.md\",\"A\\tchanges/CR-2026-0031/design-package.sha256\",\"A\\tchanges/CR-2026-0031/discovery.md\",\"A\\tchanges/CR-2026-0031/implementation.md\",\"A\\tchanges/CR-2026-0031/risk.md\",\"A\\tchanges/CR-2026-0031/source-provenance.tsv\",\"A\\tchanges/CR-2026-0031/task-package.sha256\",\"A\\tchanges/CR-2026-0031/tests.md\",\"A\\tchanges/CR-2026-0032/README.md\",\"A\\tchanges/CR-2026-0032/design-package.sha256\",\"A\\tchanges/CR-2026-0032/task-package.sha256\",\"A\\tchanges/CR-2026-0033/README.md\",\"A\\tchanges/CR-2026-0033/design-package.sha256\",\"A\\tchanges/CR-2026-0033/task-package.sha256\",\"A\\tchanges/CR-2026-0034/README.md\",\"A\\tchanges/CR-2026-0034/design-package.sha256\",\"A\\tchanges/CR-2026-0034/task-package.sha256\",\"A\\tchanges/CR-2026-0035/discovery.md\",\"A\\tchanges/CR-2026-0035/implementation.md\",\"A\\tchanges/CR-2026-0035/package.sha256\",\"A\\tchanges/CR-2026-0035/risk.md\",\"A\\tchanges/CR-2026-0035/source-provenance.tsv\",\"A\\tchanges/CR-2026-0035/tests.md\",\"A\\tchanges/CR-2026-0036/discovery.md\",\"A\\tchanges/CR-2026-0036/implementation.md\",\"A\\tchanges/CR-2026-0036/package.sha256\",\"A\\tchanges/CR-2026-0036/risk.md\",\"A\\tchanges/CR-2026-0036/source-provenance.tsv\",\"A\\tchanges/CR-2026-0036/tests.md\",\"A\\tchanges/CR-2026-0046/discovery.md\",\"A\\tchanges/CR-2026-0046/implementation.md\",\"A\\tchanges/CR-2026-0046/risk.md\",\"A\\tchanges/CR-2026-0046/source-provenance.tsv\",\"A\\tchanges/CR-2026-0046/task-package.sha256\",\"A\\tchanges/CR-2026-0046/tests.md\",\"A\\tchanges/CR-2026-0047/task-package.sha256\",\"A\\tchanges/CR-2026-0048/discovery.md\",\"A\\tchanges/CR-2026-0048/implementation.md\",\"A\\tchanges/CR-2026-0048/risk.md\",\"A\\tchanges/CR-2026-0048/source-provenance.tsv\",\"A\\tchanges/CR-2026-0048/task-package.sha256\",\"A\\tchanges/CR-2026-0048/tests.md\",\"A\\tchanges/CR-2026-0049/discovery.md\",\"A\\tchanges/CR-2026-0049/implementation.md\",\"A\\tchanges/CR-2026-0049/risk.md\",\"A\\tchanges/CR-2026-0049/source-provenance.tsv\",\"A\\tchanges/CR-2026-0049/task-package.sha256\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"9fa5851c1315be92bf7836d39b07a8ea66bf7530d2842d02f9e0f99a5e23a9e7\"},\"exists\":true,\"vm200\":{\"lines\":[\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:12:- Recovery after the initial external-network timeout uses a dedicated `skladchik-moderator-v2-edge-egress-v1` task: CT200 alone uses edge-vm `[PRIVATE_IP]` as its default gateway; edge-vm NATs only `[PRIVATE_IP]/32` into its already-existing NetBird `wt0` default exit (table 7120). No NetBird management policy is changed.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:26:Authenticated section evidence on 2026-08-12 showed 107 `discussionListItem` nodes, 106 `PreviewTooltip` markers and 517 root-relative `threads/...` hrefs. `skladchik-moderator-v2-xf1-parser-hotfix-v1` overlays only `forum.py` and `ads.py`, preserving XF2 support while adding XF1 listing/topic/message/search parsing and root-relative URL resolution. Cookie onboarding is fail-closed on the parser hotfix seal and exact installed module SHA values.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:42:The first controlled cookie apply proved the edge-vm source jar before mutation, installed it, then failed only at the v2 `auth-check`; the apply error path removed the CT200 cookie, disabled collector/competitor timers, and removed transient pve03 staging. The divergence was between two authentication classifiers: edge-vm proves the moderator session by authenticated XenForo 1 `discussionListItem` rows, while v2 still downgraded the same cookie-backed section using a text-only login heuristic. `skladchik-moderator-v2-auth-classification-hotfix-v1` preserves the sealed XF1 parser and changes only section authentication classification: a cookie-backed section that parses canonical topic rows is positive auth evidence. This is bounded by the already-observed public response yielding zero rows \",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:54:The authenticated bootstrap reached 104 listed topics and 40 detailed topics but produced zero analyses because every analyzed detail failed at `stage_history.stage = %s` with PostgreSQL `text = bytea`. The application connection inherited `SQL_ASCII`, so Psycopg returned text values as Python bytes and adapted the fetched stage back as `bytea` on the next parameterized query. The fix is at the connection boundary, not an SQL cast: `skladchik-moderator-v2-db-text-encoding-hotfix-v1` pins Psycopg `client_encoding=UTF8`, proves the baseline bytes failure against existing data, then performs a pre-mutation UTF8 probe across every existing app-facing text column and the exact formerly failing stage-history query; apply/verify repeat that proof through the installed module. No schema or data rewr\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:58:The post-cookie health failure after successful authenticated collection (104 listed topics, 17 analyses in the triggering run; 65 analyses persisted overall) was isolated to rule state. The formatting-rule fetch inherited the moderator cookie and was redirected to XenForo `/login/two-step`, creating a non-approved rule-source revision. Rule pages are public policy sources, so `skladchik-moderator-v2-rules-public-sync-hotfix-v1` fetches them through an independent cookie-free Requests session and requires the redirected final URL to preserve the expected rule thread id. Before mutation, the live dry-run requires each current public content hash to already exist as an explicitly approved historical source; a genuinely new rule revision therefore still stops for manual review and is never auto\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:62:The final cookie bootstrap exposed a collector-only SQL defect after all 104 section topics had already been detailed: `global_search_hits` used `ON CONFLICT DO UPDATE` without the unique-key inference target, so PostgreSQL rejected every whole-site duplicate-search upsert for the remaining four topics. Because detail state is committed before duplicate search and analysis, those topics then became ineligible for another detail fetch for two days. `skladchik-moderator-v2-collector-resume-hotfix-v1` fixes the upsert against the existing `UNIQUE(source_topic_id,query_kind,query_text,hit_url)` key and adds a cached-detail analysis backlog that retries topics whose latest committed detail has no analysis at or after that detail timestamp. Its dry-run executes the corrected upsert twice inside a \",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:70:After cookie onboarding is SEALED and current v2 health/timers are re-proven, `skladchik-moderator-v2-old-mvp-retirement-v1` retires only the legacy pve01 operational service. The task pins the exact legacy unit/app/rules bytes and version, captures root-only rollback copies, disables/stops the service, removes `/etc/systemd/system/skladchik-moderator-assistant.service` and `/opt/skladchik-moderator-assistant`, and preserves `/var/lib/skladchik-moderator-assistant` unchanged as inert historical state. Any apply/verify failure before seal restores the exact legacy unit/application and service state. Retirement does not touch CT200, complaints, forum state, or v2 data.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:74:The final retirement task does not delete `/opt/skladchik-moderator-assistant`. The existing app-cloud backup scheduler still schedules `skladchik-moderator-assistant`, and its worker captures `/var/lib/skladchik-moderator-assistant/state.sqlite3` plus `/opt/skladchik-moderator-assistant`. Deleting the legacy app directory would therefore break the next scheduled app backup. Retirement is corrected to disable/stop the old service and remove only its systemd unit/endpoint while preserving the exact legacy app and StateDirectory as inert, byte-pinned historical payload. The task read-only proves the existing queue/audit/worker backup contract before and after retirement; backup runtime itself is not modified.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:76:The old MVP unit uses `DynamicUser=yes` with `StateDirectory=skladchik-moderator-assistant`. Retirement accepts the normal directory layout or the exact systemd-managed `/var/lib/skladchik-moderator-assistant` symlink resolving to `/var/lib/private/skladchik-moderator-assistant`; the SQLite file itself must remain a regular non-symlink file.\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:6:4e119cef286d48ac4675235a82309e0c1087316bcada25bc6f8f43aea665e1dd tasks/skladchik-moderator-v2-application-v1/assets/app-payload.tar.gz\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:7:cf37824d4bb8d0d412d505cfeca33c81ddc37ac31ceedb6b131181653895fad1 tasks/skladchik-moderator-v2-application-v1/assets/app/config.json\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:8:761de78bd15049d408ed2f109a0fcd87e453d702defdf0e8d1547e1b35a55974 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/__init__.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:9:3e90e6c148a2b7ba52072be35280130f00fb966cfb94b76908fbd2eecd965b35 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/ads.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:10:5664ff8e9d45381a0c08a71a794060e60db8f523bd32911b390d28014066fc6c tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/analyzer.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:11:56f52f89fff1468d5e13da29c3c10cf60bc0aea06d71be871dcfc805aec23b60 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/cli.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:12:122e44d95edfc1c205cdee589ab83a9ccbce724a7951b569995e29171d4cb393 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/collector.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:13:0fd4e356a70e56f7293492b5f3d7677cc1a31156ba1964b3997c8852483edf63 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/competitors.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:14:bb207fe35de98aae0013a15eb27294e24902beeda01daf4f9b404bd8600165bc tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/config.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:15:ba63cc5d4f4e68a0cdd82c985d4fd5989fe9cf4c3beefb94ef1643d4a83bb80e tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/db.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:16:9e3bfd6a9481768800897f4a6be27e68f27e10bec96d3dda567407443b03bc99 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/forum.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:17:5b61133d9b2a72a8e5b86c01627899f60c988dee52fc7fdcc7adb7f82ebe1d47 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/normalize.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:18:88b5d4874b865ebe82ece25448a55bd083f4fb95a2c203621d715b6f0f58df57 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/rules.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:19:4c400f907b0c8fd57a4959a2d3fbc83206fd577e4429b7947e372f15c1637c25 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/schema.sql\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:20:6710a6dae5c3889412c823af20a989d2f1f072dd03451c9b1e00b6078aab570d tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/webapp.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:21:3d7e4c0054a958c6f440ffc2ee112360e1d7a433d3371590deb7575f89323f3b tasks/skladchik-moderator-v2-application-v1/assets/app/wsgi.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:22:f2f353dd56327395e03d26942deadf4987ac9b3a8a244dc87b3bddbbf9a301d9 tasks/skladchik-moderator-v2-application-v1/assets/pve03-app.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:23:04a441d36e41d30e1190dab7e71d3c05fb5733248ee7308f9b1b675abbf414b9 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.service\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:24:fee9af8ac8ab3f875a2860178b1029a1bc2fa251bf6e42a021585e02eee90c17 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.timer\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:25:d9e99cb8f07c328842f1eebc6d262dca623173cb9cfdd7e2afb4b279449a9519 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.service\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:26:37cd7bfe11a6c1cd70d5da7c62af19d7147e5f70a9641a0641cac8acbc709bb2 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.timer\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:27:9789f77fc9d6e246cacbc915b178ed2fedcf1367f7af8fe20a98881abe6597c5 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.service\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:28:a56c7d0c1bef8917f2407cabc9e27d0461b19f5af2698e556365d00673a93180 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.timer\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:29:e9cb92c0702ae26a0c6a063ffaaab0f1bafc08a82c05263509e112ff7847edae tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-web.service\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:30:6e7e7f45c756bec56a64321ebb6ca89d8f4edb8e070a57481e730e2c876deeeb tasks/skladchik-moderator-v2-application-v1/phases/apply.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:31:d17e4d6f9e9eece7672bccd18dec0fb533810fafb469e0e2ca99753fa5fe4136 tasks/skladchik-moderator-v2-application-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:32:8a39aef9926a6cf55c659937817bc5dc12657d5ef1f7edd549dc99530b88ade9 tasks/skladchik-moderator-v2-application-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:33:5157ec8da4bcfc0b88ccac54bed52a3ffeb676d5513cdb3f6b4ed5955658f76a tasks/skladchik-moderator-v2-application-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:34:403263caebb4925ada3957e0dbc852cf1813ba4ceda3fb308c33b2b22107c955 tasks/skladchik-moderator-v2-application-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:35:11f128d5da0a7c1276b77e10400e825a267633828cd173c0d8e5582902d28443 tasks/skladchik-moderator-v2-application-v1/phases/seal.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:36:3fba9b905dccf09dff024684894443d3b670b973f67c9db7653efde0b1c42fe8 tasks/skladchik-moderator-v2-application-v1/phases/verify.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:37:b9b2aa5fa48836fecbec286136377b8d6af00383df9e1a97b5ba0833c4099d27 tasks/skladchik-moderator-v2-application-v1/task.json\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:38:4b4c8d38c0e6613ec6cf2c6aaf873c506fffe5fd400566255e2a77618da7bb90 tasks/skladchik-moderator-v2-application-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:39:0c23274ab9b0ea843595689536284c86bdc7746220ebb4f140ccd1fff2c752bd tasks/skladchik-moderator-v2-application-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:40:6f9b3c541c451c4b9c0d2d394931c1b7e868349bef3e53167160298df703f2f6 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/auth-selftest.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:41:25eaabbddc54235aaafd2f5829c7e8ed9d1defcf76b8327cf347aeefda823ae0 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/forum.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:42:c2cccab25c73ec554d1a51f9dccf32343b50f5ff3efc4d65c55361032f1a2c30 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/pve03-auth-classifier.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:43:5f6e75e0b38671c55129e2975c64ab8522197f997dae370e3f513628452f1783 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/apply.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:44:caec61da54d9c40bd7cfed623617002c06a18e9604195b6057eb9e4e9bbee294 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:45:92ee9f19e3a83c1c244c033a277ed5ad312bd7396fd2b3fb9bdd4047aa847957 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:46:7c1ba5eb1e973ac5a2dd1651c89a05ba5a133f5bcf59ec216395887f9019ed7b tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:47:1c95a608369828b9da7c5d78fe630b5b4d947a799cbd22006a02be85686d5d75 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:48:2ab9124cc1428a68ca55c86fe6184f9fce8885dc353218a2caa2d8af742f0c89 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/seal.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:49:06e4185e2678a7e8a71514dd41b1845e84b1099f98003e234929aaa23d1c5d4a tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/verify.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:50:40ed940ba18618988294feede2a24d825a95c8a9ba84d5491f46664466be6b2e tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/task.json\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:51:3d0827c41d83923e0672d2d07f0502f42abc55b825f2f5e5c42dafa851c69419 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:52:49c5c42d757ee1e37123a5dc945d2a17631b74c394dbcd621e90ed7ad132cc72 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:53:011936d623941792240f8687443220e81357b68b17d419ebcdaa721d0473c63b tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/edge-cookie-source.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:54:56a9ab7d9169987c3b8fae6de29e6a3adb4538e34664d1b77c8c6203a9003474 tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/pve03-cookie.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:55:fb70f92b602588b73eb7eec5816387669576b5de2e07b69ff90de328bef3026b tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/apply.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:56:1ed1ad4b17f96dee387b23989b3e3a974ed501cd5d694cade4d085d52dd295a1 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:57:a839dd24e8b7c786b3130bd716841e0ced43c49ea1ab3314aebbeaca07dfd436 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:58:e377d14af824721cc1986889f1291da70b87901d1837769390d378f4d2fe5e13 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:59:014cf33ef917d193385449fc13201cefa84148608eb4fd6d3e5f30be06d1dd73 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:60:268b03a7b39225bfb2c97c4c87827c819e2ed727138b6158ff976469daf6887a tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/seal.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:61:6dafb047863c6df90898beeb99dd5ef04862afae3b8a3af57eb8290c671434a6 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/verify.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:62:feec58b4018f777a212520a795e7605455c6fb41da7a1792b60e1d57981c4689 tasks/skladchik-moderator-v2-cookie-onboarding-v1/task.json\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:63:4a8ae4ac4d749a4a7d10b8a21d2729dc2242ef4b0cd3b06f28ac89dd2bbff92c tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:64:93cb00411e45d9bdd9cb035869fe2be230f6147e76a8898a36606c51d9bcb568 tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:65:2ee3682cb57e7b6d04195a37b8f7acafde5cb2dc9ca28820e25c7143b3db4706 tasks/skladchik-moderator-v2-edge-egress-v1/assets/edge-egress.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:66:207793e2fa360abb88d535912d7d013af8bc822f4ffb1d8f55a3ea0967dc1ad6 tasks/skladchik-moderator-v2-edge-egress-v1/assets/pve03-egress.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:67:3c32c482e3232df8a2c4d25f553e8e7198c33a378e0600f53c01f71d14d9b3f6 tasks/skladchik-moderator-v2-edge-egress-v1/phases/apply.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:68:c51e41420b857f7d0ff2b8a16c8d0a339b4b942020d4ae59f80721e113e37eec tasks/skladchik-moderator-v2-edge-egress-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:69:d5e83720f2d842f4a1a2aba7ae4a55ce5494d16a43aa67f280d21c3cbed74d16 tasks/skladchik-moderator-v2-edge-egress-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:70:ee7ba739521639244e37ecf63d218bc18202701e53970f46eb987f7f3c6cb3b5 tasks/skladchik-moderator-v2-edge-egress-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:71:23aa44a61d9a6197ef236cc71b3f5eb4f9c38cdb24ae68eaa52113d34ac96ac0 tasks/skladchik-moderator-v2-edge-egress-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:72:ef7485307bd7e9b49c9102268db8b729049226f631441362ad3c2c5227516c12 tasks/skladchik-moderator-v2-edge-egress-v1/phases/seal.sh\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"9989ff793d051a8863587f029c5c474bae7c794adc87d6e9e566a31f62e43b6c\"}},\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry\":{\"diff_names\":{\"lines\":[\"D\\t.gitea/workflows/validate-kb.yml\",\"M\\tACTIVE_CHANGES.md\",\"M\\tAGENTS.md\",\"M\\tCURRENT_CONTEXT.md\",\"D\\tKB_START_HERE.md\",\"M\\tREADME.md\",\"D\\tchanges/CR-2026-0018/acceptance.json\",\"D\\tchanges/CR-2026-0018/caller-inventory-requirements.md\",\"D\\tchanges/CR-2026-0018/design.md\",\"A\\tchanges/CR-2026-0018/evidence.md\",\"D\\tchanges/CR-2026-0018/execution-contract.md\",\"A\\tchanges/CR-2026-0018/plan.json\",\"D\\tchanges/CR-2026-0018/plan.md\",\"D\\tchanges/CR-2026-0018/regression-cases-draft.json\",\"D\\tchanges/CR-2026-0018/request.json\",\"D\\tchanges/CR-2026-0018/review-decision.md\",\"M\\tchanges/CR-2026-0018/risk.md\",\"M\\tchanges/CR-2026-0018/rollback.md\",\"A\\tchanges/CR-2026-0018/task-package.sha256\",\"D\\tchanges/CR-2026-0018/task-reference.md\",\"M\\tchanges/CR-2026-0018/tests.md\",\"D\\tchanges/CR-2026-0018/threat-model.md\",\"A\\tchanges/CR-2026-0019/evidence.md\",\"A\\tchanges/CR-2026-0019/plan.json\",\"A\\tchanges/CR-2026-0019/risk.md\",\"A\\tchanges/CR-2026-0019/rollback.md\",\"A\\tchanges/CR-2026-0019/source-freeze.sha256\",\"A\\tchanges/CR-2026-0019/task-package.sha256\",\"A\\tchanges/CR-2026-0019/tests.md\",\"A\\tchanges/CR-2026-0026/design-package.sha256\",\"A\\tchanges/CR-2026-0026/discovery.md\",\"A\\tchanges/CR-2026-0026/implementation.md\",\"A\\tchanges/CR-2026-0026/plan.json\",\"A\\tchanges/CR-2026-0026/risk.md\",\"A\\tchanges/CR-2026-0026/rollback.md\",\"A\\tchanges/CR-2026-0026/source-provenance.tsv\",\"A\\tchanges/CR-2026-0026/task-package.sha256\",\"A\\tchanges/CR-2026-0026/tests.md\",\"A\\tchanges/CR-2026-0027/design-package.sha256\",\"A\\tchanges/CR-2026-0027/discovery.md\",\"A\\tchanges/CR-2026-0027/implementation.md\",\"A\\tchanges/CR-2026-0027/plan.json\",\"A\\tchanges/CR-2026-0027/risk.md\",\"A\\tchanges/CR-2026-0027/rollback.md\",\"A\\tchanges/CR-2026-0027/source-provenance.tsv\",\"A\\tchanges/CR-2026-0027/task-package.sha256\",\"A\\tchanges/CR-2026-0027/tests.md\",\"A\\tchanges/CR-2026-0028/design-package.sha256\",\"A\\tchanges/CR-2026-0028/discovery.md\",\"A\\tchanges/CR-2026-0028/implementation.md\",\"A\\tchanges/CR-2026-0028/plan.json\",\"A\\tchanges/CR-2026-0028/risk.md\",\"A\\tchanges/CR-2026-0028/rollback.md\",\"A\\tchanges/CR-2026-0028/source-provenance.tsv\",\"A\\tchanges/CR-2026-0028/task-package.sha256\",\"A\\tchanges/CR-2026-0028/tests.md\",\"A\\tchanges/CR-2026-0029/design-package.sha256\",\"A\\tchanges/CR-2026-0029/discovery.md\",\"A\\tchanges/CR-2026-0029/implementation.md\",\"A\\tchanges/CR-2026-0029/plan.json\",\"A\\tchanges/CR-2026-0029/risk.md\",\"A\\tchanges/CR-2026-0029/rollback.md\",\"A\\tchanges/CR-2026-0029/source-provenance.tsv\",\"A\\tchanges/CR-2026-0029/task-package.sha256\",\"A\\tchanges/CR-2026-0029/tests.md\",\"A\\tchanges/CR-2026-0030/design-package.sha256\",\"A\\tchanges/CR-2026-0030/discovery.md\",\"A\\tchanges/CR-2026-0030/implementation.md\",\"A\\tchanges/CR-2026-0030/plan.json\",\"A\\tchanges/CR-2026-0030/risk.md\",\"A\\tchanges/CR-2026-0030/rollback.md\",\"A\\tchanges/CR-2026-0030/source-provenance.tsv\",\"A\\tchanges/CR-2026-0030/task-package.sha256\",\"A\\tchanges/CR-2026-0030/tests.md\",\"A\\tchanges/CR-2026-0031/design-package.sha256\",\"A\\tchanges/CR-2026-0031/discovery.md\",\"A\\tchanges/CR-2026-0031/implementation.md\",\"A\\tchanges/CR-2026-0031/risk.md\",\"A\\tchanges/CR-2026-0031/source-provenance.tsv\",\"A\\tchanges/CR-2026-0031/task-package.sha256\",\"A\\tchanges/CR-2026-0031/tests.md\",\"A\\tchanges/CR-2026-0032/README.md\",\"A\\tchanges/CR-2026-0032/design-package.sha256\",\"A\\tchanges/CR-2026-0032/task-package.sha256\",\"A\\tchanges/CR-2026-0033/README.md\",\"A\\tchanges/CR-2026-0033/design-package.sha256\",\"A\\tchanges/CR-2026-0033/task-package.sha256\",\"A\\tchanges/CR-2026-0034/README.md\",\"A\\tchanges/CR-2026-0034/design-package.sha256\",\"A\\tchanges/CR-2026-0034/task-package.sha256\",\"A\\tchanges/CR-2026-0035/discovery.md\",\"A\\tchanges/CR-2026-0035/implementation.md\",\"A\\tchanges/CR-2026-0035/package.sha256\",\"A\\tchanges/CR-2026-0035/risk.md\",\"A\\tchanges/CR-2026-0035/source-provenance.tsv\",\"A\\tchanges/CR-2026-0035/tests.md\",\"A\\tchanges/CR-2026-0036/discovery.md\",\"A\\tchanges/CR-2026-0036/implementation.md\",\"A\\tchanges/CR-2026-0036/package.sha256\",\"A\\tchanges/CR-2026-0036/risk.md\",\"A\\tchanges/CR-2026-0036/source-provenance.tsv\",\"A\\tchanges/CR-2026-0036/tests.md\",\"A\\tchanges/CR-2026-0046/discovery.md\",\"A\\tchanges/CR-2026-0046/implementation.md\",\"A\\tchanges/CR-2026-0046/risk.md\",\"A\\tchanges/CR-2026-0046/source-provenance.tsv\",\"A\\tchanges/CR-2026-0046/task-package.sha256\",\"A\\tchanges/CR-2026-0046/tests.md\",\"A\\tchanges/CR-2026-0047/task-package.sha256\",\"A\\tchanges/CR-2026-0048/discovery.md\",\"A\\tchanges/CR-2026-0048/implementation.md\",\"A\\tchanges/CR-2026-0048/risk.md\",\"A\\tchanges/CR-2026-0048/source-provenance.tsv\",\"A\\tchanges/CR-2026-0048/task-package.sha256\",\"A\\tchanges/CR-2026-0048/tests.md\",\"A\\tchanges/CR-2026-0049/discovery.md\",\"A\\tchanges/CR-2026-0049/implementation.md\",\"A\\tchanges/CR-2026-0049/risk.md\",\"A\\tchanges/CR-2026-0049/source-provenance.tsv\",\"A\\tchanges/CR-2026-0049/task-package.sha256\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"4ab8dd56aa0daea12c6e08fea70070d993d1984ca1d9ec99b9a210bc995e0d0a\"},\"exists\":true,\"vm200\":{\"lines\":[\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:12:- Recovery after the initial external-network timeout uses a dedicated `skladchik-moderator-v2-edge-egress-v1` task: CT200 alone uses edge-vm `[PRIVATE_IP]` as its default gateway; edge-vm NATs only `[PRIVATE_IP]/32` into its already-existing NetBird `wt0` default exit (table 7120). No NetBird management policy is changed.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:26:Authenticated section evidence on 2026-08-12 showed 107 `discussionListItem` nodes, 106 `PreviewTooltip` markers and 517 root-relative `threads/...` hrefs. `skladchik-moderator-v2-xf1-parser-hotfix-v1` overlays only `forum.py` and `ads.py`, preserving XF2 support while adding XF1 listing/topic/message/search parsing and root-relative URL resolution. Cookie onboarding is fail-closed on the parser hotfix seal and exact installed module SHA values.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:42:The first controlled cookie apply proved the edge-vm source jar before mutation, installed it, then failed only at the v2 `auth-check`; the apply error path removed the CT200 cookie, disabled collector/competitor timers, and removed transient pve03 staging. The divergence was between two authentication classifiers: edge-vm proves the moderator session by authenticated XenForo 1 `discussionListItem` rows, while v2 still downgraded the same cookie-backed section using a text-only login heuristic. `skladchik-moderator-v2-auth-classification-hotfix-v1` preserves the sealed XF1 parser and changes only section authentication classification: a cookie-backed section that parses canonical topic rows is positive auth evidence. This is bounded by the already-observed public response yielding zero rows\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:54:The authenticated bootstrap reached 104 listed topics and 40 detailed topics but produced zero analyses because every analyzed detail failed at `stage_history.stage = %s` with PostgreSQL `text = bytea`. The application connection inherited `SQL_ASCII`, so Psycopg returned text values as Python bytes and adapted the fetched stage back as `bytea` on the next parameterized query. The fix is at the connection boundary, not an SQL cast: `skladchik-moderator-v2-db-text-encoding-hotfix-v1` pins Psycopg `client_encoding=UTF8`, proves the baseline bytes failure against existing data, then performs a pre-mutation UTF8 probe across every existing app-facing text column and the exact formerly failing stage-history query; apply/verify repeat that proof through the installed module. No schema or data rew\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:58:The post-cookie health failure after successful authenticated collection (104 listed topics, 17 analyses in the triggering run; 65 analyses persisted overall) was isolated to rule state. The formatting-rule fetch inherited the moderator cookie and was redirected to XenForo `/login/two-step`, creating a non-approved rule-source revision. Rule pages are public policy sources, so `skladchik-moderator-v2-rules-public-sync-hotfix-v1` fetches them through an independent cookie-free Requests session and requires the redirected final URL to preserve the expected rule thread id. Before mutation, the live dry-run requires each current public content hash to already exist as an explicitly approved historical source; a genuinely new rule revision therefore still stops for manual review and is never aut\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:62:The final cookie bootstrap exposed a collector-only SQL defect after all 104 section topics had already been detailed: `global_search_hits` used `ON CONFLICT DO UPDATE` without the unique-key inference target, so PostgreSQL rejected every whole-site duplicate-search upsert for the remaining four topics. Because detail state is committed before duplicate search and analysis, those topics then became ineligible for another detail fetch for two days. `skladchik-moderator-v2-collector-resume-hotfix-v1` fixes the upsert against the existing `UNIQUE(source_topic_id,query_kind,query_text,hit_url)` key and adds a cached-detail analysis backlog that retries topics whose latest committed detail has no analysis at or after that detail timestamp. Its dry-run executes the corrected upsert twice inside a\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:70:After cookie onboarding is SEALED and current v2 health/timers are re-proven, `skladchik-moderator-v2-old-mvp-retirement-v1` retires only the legacy pve01 operational service. The task pins the exact legacy unit/app/rules bytes and version, captures root-only rollback copies, disables/stops the service, removes `/etc/systemd/system/skladchik-moderator-assistant.service` and `/opt/skladchik-moderator-assistant`, and preserves `/var/lib/skladchik-moderator-assistant` unchanged as inert historical state. Any apply/verify failure before seal restores the exact legacy unit/application and service state. Retirement does not touch CT200, complaints, forum state, or v2 data.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:74:The final retirement task does not delete `/opt/skladchik-moderator-assistant`. The existing app-cloud backup scheduler still schedules `skladchik-moderator-assistant`, and its worker captures `/var/lib/skladchik-moderator-assistant/state.sqlite3` plus `/opt/skladchik-moderator-assistant`. Deleting the legacy app directory would therefore break the next scheduled app backup. Retirement is corrected to disable/stop the old service and remove only its systemd unit/endpoint while preserving the exact legacy app and StateDirectory as inert, byte-pinned historical payload. The task read-only proves the existing queue/audit/worker backup contract before and after retirement; backup runtime itself is not modified.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:76:The old MVP unit uses `DynamicUser=yes` with `StateDirectory=skladchik-moderator-assistant`. Retirement accepts the normal directory layout or the exact systemd-managed `/var/lib/skladchik-moderator-assistant` symlink resolving to `/var/lib/private/skladchik-moderator-assistant`; the SQLite file itself must remain a regular non-symlink file.\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:6:4e119cef286d48ac4675235a82309e0c1087316bcada25bc6f8f43aea665e1dd tasks/skladchik-moderator-v2-application-v1/assets/app-payload.tar.gz\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:7:cf37824d4bb8d0d412d505cfeca33c81ddc37ac31ceedb6b131181653895fad1 tasks/skladchik-moderator-v2-application-v1/assets/app/config.json\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:8:761de78bd15049d408ed2f109a0fcd87e453d702defdf0e8d1547e1b35a55974 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/__init__.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:9:3e90e6c148a2b7ba52072be35280130f00fb966cfb94b76908fbd2eecd965b35 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/ads.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:10:5664ff8e9d45381a0c08a71a794060e60db8f523bd32911b390d28014066fc6c tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/analyzer.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:11:56f52f89fff1468d5e13da29c3c10cf60bc0aea06d71be871dcfc805aec23b60 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/cli.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:12:122e44d95edfc1c205cdee589ab83a9ccbce724a7951b569995e29171d4cb393 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/collector.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:13:0fd4e356a70e56f7293492b5f3d7677cc1a31156ba1964b3997c8852483edf63 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/competitors.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:14:bb207fe35de98aae0013a15eb27294e24902beeda01daf4f9b404bd8600165bc tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/config.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:15:ba63cc5d4f4e68a0cdd82c985d4fd5989fe9cf4c3beefb94ef1643d4a83bb80e tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/db.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:16:9e3bfd6a9481768800897f4a6be27e68f27e10bec96d3dda567407443b03bc99 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/forum.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:17:5b61133d9b2a72a8e5b86c01627899f60c988dee52fc7fdcc7adb7f82ebe1d47 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/normalize.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:18:88b5d4874b865ebe82ece25448a55bd083f4fb95a2c203621d715b6f0f58df57 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/rules.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:19:4c400f907b0c8fd57a4959a2d3fbc83206fd577e4429b7947e372f15c1637c25 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/schema.sql\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:20:6710a6dae5c3889412c823af20a989d2f1f072dd03451c9b1e00b6078aab570d tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/webapp.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:21:3d7e4c0054a958c6f440ffc2ee112360e1d7a433d3371590deb7575f89323f3b tasks/skladchik-moderator-v2-application-v1/assets/app/wsgi.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:22:f2f353dd56327395e03d26942deadf4987ac9b3a8a244dc87b3bddbbf9a301d9 tasks/skladchik-moderator-v2-application-v1/assets/pve03-app.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:23:04a441d36e41d30e1190dab7e71d3c05fb5733248ee7308f9b1b675abbf414b9 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.service\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:24:fee9af8ac8ab3f875a2860178b1029a1bc2fa251bf6e42a021585e02eee90c17 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.timer\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:25:d9e99cb8f07c328842f1eebc6d262dca623173cb9cfdd7e2afb4b279449a9519 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.service\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:26:37cd7bfe11a6c1cd70d5da7c62af19d7147e5f70a9641a0641cac8acbc709bb2 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.timer\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:27:9789f77fc9d6e246cacbc915b178ed2fedcf1367f7af8fe20a98881abe6597c5 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.service\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:28:a56c7d0c1bef8917f2407cabc9e27d0461b19f5af2698e556365d00673a93180 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.timer\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:29:e9cb92c0702ae26a0c6a063ffaaab0f1bafc08a82c05263509e112ff7847edae tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-web.service\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:30:6e7e7f45c756bec56a64321ebb6ca89d8f4edb8e070a57481e730e2c876deeeb tasks/skladchik-moderator-v2-application-v1/phases/apply.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:31:d17e4d6f9e9eece7672bccd18dec0fb533810fafb469e0e2ca99753fa5fe4136 tasks/skladchik-moderator-v2-application-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:32:8a39aef9926a6cf55c659937817bc5dc12657d5ef1f7edd549dc99530b88ade9 tasks/skladchik-moderator-v2-application-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:33:5157ec8da4bcfc0b88ccac54bed52a3ffeb676d5513cdb3f6b4ed5955658f76a tasks/skladchik-moderator-v2-application-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:34:403263caebb4925ada3957e0dbc852cf1813ba4ceda3fb308c33b2b22107c955 tasks/skladchik-moderator-v2-application-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:35:11f128d5da0a7c1276b77e10400e825a267633828cd173c0d8e5582902d28443 tasks/skladchik-moderator-v2-application-v1/phases/seal.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:36:3fba9b905dccf09dff024684894443d3b670b973f67c9db7653efde0b1c42fe8 tasks/skladchik-moderator-v2-application-v1/phases/verify.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:37:b9b2aa5fa48836fecbec286136377b8d6af00383df9e1a97b5ba0833c4099d27 tasks/skladchik-moderator-v2-application-v1/task.json\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:38:4b4c8d38c0e6613ec6cf2c6aaf873c506fffe5fd400566255e2a77618da7bb90 tasks/skladchik-moderator-v2-application-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:39:0c23274ab9b0ea843595689536284c86bdc7746220ebb4f140ccd1fff2c752bd tasks/skladchik-moderator-v2-application-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:40:6f9b3c541c451c4b9c0d2d394931c1b7e868349bef3e53167160298df703f2f6 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/auth-selftest.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:41:25eaabbddc54235aaafd2f5829c7e8ed9d1defcf76b8327cf347aeefda823ae0 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/forum.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:42:c2cccab25c73ec554d1a51f9dccf32343b50f5ff3efc4d65c55361032f1a2c30 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/pve03-auth-classifier.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:43:5f6e75e0b38671c55129e2975c64ab8522197f997dae370e3f513628452f1783 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/apply.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:44:caec61da54d9c40bd7cfed623617002c06a18e9604195b6057eb9e4e9bbee294 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:45:92ee9f19e3a83c1c244c033a277ed5ad312bd7396fd2b3fb9bdd4047aa847957 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:46:7c1ba5eb1e973ac5a2dd1651c89a05ba5a133f5bcf59ec216395887f9019ed7b tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:47:1c95a608369828b9da7c5d78fe630b5b4d947a799cbd22006a02be85686d5d75 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:48:2ab9124cc1428a68ca55c86fe6184f9fce8885dc353218a2caa2d8af742f0c89 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/seal.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:49:06e4185e2678a7e8a71514dd41b1845e84b1099f98003e234929aaa23d1c5d4a tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/verify.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:50:40ed940ba18618988294feede2a24d825a95c8a9ba84d5491f46664466be6b2e tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/task.json\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:51:3d0827c41d83923e0672d2d07f0502f42abc55b825f2f5e5c42dafa851c69419 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:52:49c5c42d757ee1e37123a5dc945d2a17631b74c394dbcd621e90ed7ad132cc72 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:53:011936d623941792240f8687443220e81357b68b17d419ebcdaa721d0473c63b tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/edge-cookie-source.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:54:56a9ab7d9169987c3b8fae6de29e6a3adb4538e34664d1b77c8c6203a9003474 tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/pve03-cookie.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:55:fb70f92b602588b73eb7eec5816387669576b5de2e07b69ff90de328bef3026b tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/apply.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:56:1ed1ad4b17f96dee387b23989b3e3a974ed501cd5d694cade4d085d52dd295a1 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:57:a839dd24e8b7c786b3130bd716841e0ced43c49ea1ab3314aebbeaca07dfd436 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:58:e377d14af824721cc1986889f1291da70b87901d1837769390d378f4d2fe5e13 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:59:014cf33ef917d193385449fc13201cefa84148608eb4fd6d3e5f30be06d1dd73 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:60:268b03a7b39225bfb2c97c4c87827c819e2ed727138b6158ff976469daf6887a tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/seal.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:61:6dafb047863c6df90898beeb99dd5ef04862afae3b8a3af57eb8290c671434a6 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/verify.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:62:feec58b4018f777a212520a795e7605455c6fb41da7a1792b60e1d57981c4689 tasks/skladchik-moderator-v2-cookie-onboarding-v1/task.json\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:63:4a8ae4ac4d749a4a7d10b8a21d2729dc2242ef4b0cd3b06f28ac89dd2bbff92c tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/runtime-lib.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:64:93cb00411e45d9bdd9cb035869fe2be230f6147e76a8898a36606c51d9bcb568 tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/test_contract.py\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:65:2ee3682cb57e7b6d04195a37b8f7acafde5cb2dc9ca28820e25c7143b3db4706 tasks/skladchik-moderator-v2-edge-egress-v1/assets/edge-egress.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:66:207793e2fa360abb88d535912d7d013af8bc822f4ffb1d8f55a3ea0967dc1ad6 tasks/skladchik-moderator-v2-edge-egress-v1/assets/pve03-egress.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:67:3c32c482e3232df8a2c4d25f553e8e7198c33a378e0600f53c01f71d14d9b3f6 tasks/skladchik-moderator-v2-edge-egress-v1/phases/apply.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:68:c51e41420b857f7d0ff2b8a16c8d0a339b4b942020d4ae59f80721e113e37eec tasks/skladchik-moderator-v2-edge-egress-v1/phases/dry-run.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:69:d5e83720f2d842f4a1a2aba7ae4a55ce5494d16a43aa67f280d21c3cbed74d16 tasks/skladchik-moderator-v2-edge-egress-v1/phases/preflight.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:70:ee7ba739521639244e37ecf63d218bc18202701e53970f46eb987f7f3c6cb3b5 tasks/skladchik-moderator-v2-edge-egress-v1/phases/prepare.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:71:23aa44a61d9a6197ef236cc71b3f5eb4f9c38cdb24ae68eaa52113d34ac96ac0 tasks/skladchik-moderator-v2-edge-egress-v1/phases/rollback.sh\",\"refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:72:ef7485307bd7e9b49c9102268db8b729049226f631441362ad3c2c5227516c12 tasks/skladchik-moderator-v2-edge-egress-v1/phases/seal.sh\"],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"7fd8c45be9f29ec20392475bb0f6d6e2fe4e944bfd3b954b363ede77248b3bb6\"}}},\"status\":{\"lines\":[],\"rc\":0,\"stderr_sha256\":null,\"stdout_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"}}\nPVE_ACTIVE_INVENTORY={\"rc\":0,\"rows\":[{\"name\":\"dns1\",\"node\":\"pve01\",\"status\":\"running\",\"type\":\"lxc\",\"vmid\":110},{\"name\":\"dns2\",\"node\":\"pve02\",\"status\":\"running\",\"type\":\"lxc\",\"vmid\":111},{\"name\":\"unbound1\",\"node\":\"pve01\",\"status\":\"running\",\"type\":\"lxc\",\"vmid\":112},{\"name\":\"unbound2\",\"node\":\"pve02\",\"status\":\"running\",\"type\":\"lxc\",\"vmid\":113},{\"name\":\"edge-vm\",\"node\":\"pve03\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":130},{\"name\":\"snikket\",\"node\":\"pve01\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":150},{\"name\":\"forum-prod\",\"node\":\"pve02\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":160},{\"name\":\"core-apps\",\"node\":\"pve01\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":170},{\"name\":\"monitoring\",\"node\":\"pve01\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":171},{\"name\":\"homelab-ops-worker\",\"node\":\"pve03\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":190},{\"name\":\"newfi-prod\",\"node\":\"pve01\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":210},{\"name\":\"newfi-staging\",\"node\":\"pve03\",\"status\":\"running\",\"type\":\"qemu\",\"vmid\":211},{\"name\":\"edge-cold-standby\",\"node\":\"pve02\",\"status\":\"stopped\",\"type\":\"qemu\",\"vmid\":9130}],\"stderr_sha256\":null}\nSTATUS=OK\nCHANGES_MADE=false\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260916-INFRA-DR-BACKUPV2-LEGACY-PVE-RETENTION-SOURCE-CAPTURE-489R1\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\n" + "output": "APP484_BEGIN\nAPP484_DECISION=PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK\nAPP484_NEXT_GATE=READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1\nAPP484_CANARY_DOMAIN=codevipe.ru\nAPP484_NATIVE_ACTION_PATHS_EXERCISED=2\nAPP484_ENTITY_SAVE_CALLS=3\nAPP484_ROLLBACK_STARTED=True\nAPP484_ROLLBACK_RESTORED=True\nAPP484_PERSISTENT_DRIFT_DETECTED=False\nAPP484_SAFE_REPORT={\"aggregate_restored\":true,\"anchor_483_commit\":\"6e5d92e225838298271af5e98956767c04fc065c\",\"anchor_483_decision\":\"PASS_NATIVE_ACTION_SEMANTICS_INVENTORY_READY\",\"auto_mutation_authorized\":false,\"backup_dr_mutations\":0,\"bounce_mid_visible\":true,\"canary_domain\":\"codevipe.ru\",\"changes_made\":true,\"command_id\":\"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1\",\"commit_operations\":0,\"database_mutations\":2,\"decision\":\"PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK\",\"dns_mutations\":0,\"domain\":\"codevipe.ru\",\"entity_api_canary\":true,\"entity_save_calls\":3,\"failure_label\":\"\",\"initial_receive_admin_email\":0,\"initial_user_state\":\"valid\",\"mail_mutations\":0,\"mail_send_operations\":0,\"native_action_paths_exercised\":2,\"native_bounce_processor_invoked\":false,\"native_bounce_processor_presence_gated\":true,\"next_gate\":\"READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1\",\"ok\":true,\"persistent_drift_detected\":false,\"persistent_mutation_authorized\":false,\"postbox_mutations\":0,\"processor_method_parameter_count\":1,\"processor_method_present\":true,\"processor_method_tokens_ok\":true,\"qga_160_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"qga_160_stdout_sha256\":\"d0e40b371b64a28a74d8ee38ab3eeb27c5b7942835c1e744414b4dff617cc911\",\"qga_160_transport_rc\":0,\"raw_sql_write_operations\":0,\"rollback_restored\":true,\"rollback_started\":true,\"selected_fields_restored\":true,\"subject_class\":\"VALID_NONBANNED_NONPRIVILEGED_WITH_OPTION_ROW\",\"transactional_rollback_only\":true,\"unsubscribe_false_mid_visible\":true,\"unsubscribe_roundtrip_from_zero\":true,\"xenforo_mutations\":2,\"xf_version_id\":2031170,\"xf_version_string\":\"2.3.11\"}\nHOMELAB_RESULT_CONTRACT={\"changes_made\":true,\"command_id\":\"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1\",\"rollback_restored\":true,\"rollback_started\":true,\"status\":\"OK\",\"version\":1}\nAPP484_END\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index 58456e59..99e9ce67 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,55 +1,44 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260916-INFRA-DR-BACKUPV2-LEGACY-PVE-RETENTION-SOURCE-CAPTURE-489R1 +COMMAND_ID=SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1 STATUS=OK RC=0 HOST=pve01 -MODE=read-only -COMPONENT=infra-dr-backupv2-legacy-pve-retention-source-capture +MODE=change +COMPONENT=xenforo-app-policy-native-action-transactional-canary REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=45aee1dd4582048afc3a1893c770533d881e663514524acddbccf3a9685edc9b +COMMAND_SHA256=d835baf1e739fa0fa6c94345f2ad0697814f32ff5efb76eaece0af78c6bb21c6 DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true -CHANGE_DECLARED=false +CHANGE_DECLARED=true RESULT_CONTRACT_VALID=true -RESULT_CONTRACT_STATUS=NOT_APPLICABLE +RESULT_CONTRACT_STATUS=OK RESULT_CONTRACT_ERROR=NONE COMMAND_RC=0 -CHANGES_MADE=false -ROLLBACK_STARTED=false -ROLLBACK_RESTORED=null -MUTATION_OUTCOME=NO_MUTATION +CHANGES_MADE=true +ROLLBACK_STARTED=true +ROLLBACK_RESTORED=true +MUTATION_OUTCOME=ROLLED_BACK SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=87ab0715c0a1ecdb6af4b9bca6d13dea8fee4e52aa04edf113ad69329149d286 -SANITIZED_OUTPUT_SHA256=7c8ac17b371d7c485cbd9c1a7c4097ffa6cf649306bdb7ee68326ee8d9484e9c +RAW_EVIDENCE_SHA256=0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9 +SANITIZED_OUTPUT_SHA256=0d9d01422f826f4105a1ab63043ad02028f6d066272e54c23ec54f77493b6dd9 OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260916-INFRA-DR-BACKUPV2-LEGACY-PVE-RETENTION-SOURCE-CAPTURE-489R1 -SCOPE=READ_ONLY_SOURCE_AUTHORITY_CAPTURE_NO_BACKUP_NO_CLOUD_NO_MUTATION -IDENTITIES={"adapter":"18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3","engine":"dbfd237ddae5d2199bd8567ec6880d11276631dcc45acb49967de97329524037","gfs":null,"legacy":"b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7","policy":"e06b7e6285eda2885ef913aa954a70abc7c1d892199a8b7cea2ada98b8edba34","pve265":"cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be","pve270":"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef","retention":"8adb6c10f5911f39c53775b89eac3cd1823f1ed34b4caccade5279c213e998a3","seal":"f508adc9b09bad9692c580e642018f5d3dbf223fc572ee62478466fd517234fa","targets":"a723befc7fd42d70af9088406598f18156dc3b4c76d8b34c4bb725dfaa48dd38"} -BASELINE_MATCH={"engine":true,"retention":true,"seal":true,"targets":true} -LEGACY_CAPTURE_PVE_GUEST={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py","file_sha256":"b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7","lines":["def capture_pve_guest(t,gen,work):"," vmid=int(t['vmid']); rows=[r for r in cluster_inventory() if int(r.get('vmid',-1))==vmid]"," if len(rows)!=1: raise BackupError('PVE_GUEST_NOT_UNIQUE')"," row=rows[0]; node=row.get('node'); typ=row.get('type')"," if typ!=t['guest_type']: raise BackupError('PVE_GUEST_TYPE_DRIFT')"," if typ=='lxc':"," _require_exact_source(P270,P270_SHA,'P270_IDENTITY');_require_exact_source(P282,P282_SHA,'P282_IDENTITY')"," _default_unprivileged_lxc(node,vmid)"," scratch=f'/var/tmp/homelab-vzdump-v2-{gen}'"," ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)"," q=ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)"," if q.stdout.decode().strip()!='710:0:100000': raise BackupError('PVE_MAPPED_SCRATCH_ACCESS_CONTRACT')"," try:"," mapped_scratch_probe(node,scratch)"," argv,job=proven_lxc_dump_argv(t,row,node,scratch)"," local=work/'payload.bin'"," _stream_argv_to_local(node,argv,local,timeout=7200)"," if local.stat().st_size>int(job['archive_cap_bytes']): raise BackupError('VZDUMP_ARCHIVE_CAP_EXCEEDED')"," except Exception:"," ssh_remote(node,['rm','-rf','--',scratch],timeout=60,check=False);raise"," cleanup={'kind':'pve_source_dir','node':node,'path':scratch}"," return local,{'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':typ,'node':node,'status':row.get('status'),'producer_contract':'proven-270-282-stream'},cleanup"," # QEMU path remains unchanged: bounded dedicated dumpdir with later cloud readback/reconstruction."," srcdir=f'/var/tmp/homelab-vzdump-v2-{gen}'"," ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)"," try:"," ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200)"," p=ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\\n'],timeout=30)"," files=[x for x in p.stdout.decode().splitlines() if x.strip()]"," if len(files)!=1: raise BackupError('VZDUMP_OUTPUT_NOT_UNIQUE')"," src=files[0];local=work/'payload.bin'"," if node=='pve01': local=pathlib.Path(src)"," else: run([SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)"," if not pathlib.Path(local).is_file() or pathlib.Path(local).stat().st_size<=0: raise BackupError('VZDUMP_PAYLOAD_MISSING')"," except Exception:"," ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False);raise"," return pathlib.Path(local),{'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':typ,'node':node,'status':row.get('status')},{'kind':'pve_source_dir','node':node,'path':srcdir}"],"name":"capture_pve_guest","source_sha256":"c4c22625a9c6a954d0ed93dfc63f0501af0644ca9f5e6781d3b2e50a7e2563ea"} -LEGACY_CAPTURE_TARGET={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py","file_sha256":"b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7","lines":["def capture_target(t,gen,work):"," typ=t['type']"," if typ=='pve_guest': return capture_pve_guest(t,gen,work)"," if typ=='pve_node_bundle': return capture_node_bundle(t,gen,work)"," if typ=='vps_md': return capture_vps_md(t,gen,work)"," if typ=='vps_spb': return capture_vps_spb(t,gen,work)"," if typ=='vps_us': return capture_vps_us(t,gen,work)"," if typ=='router': return capture_router(t,gen,work)"," if typ=='xenforo': return capture_xenforo(t,gen,work)"," raise BackupError('CAPTURE_TYPE_UNKNOWN')"],"name":"capture_target","source_sha256":"f52cec3a28467da247da0efaffb9523a775b1bb0cab2ce7fef1b1a5923a765bb"} -PVE265_DUMP_ARGV={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py","file_sha256":"cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be","lines":["def dump_argv(job,executable,tmpdir,now):"," validate_job(job,now)"," need(path_ok(executable) and path_ok(tmpdir),'EXECUTION_PATH')"," return [str(executable),str(job['vmid']),'--node',job['node'],'--mode','snapshot','--stdout','1',"," '--compress','zstd','--zstd','1','--remove','0','--prune-backups','keep-all=1',"," '--stdexcludes','0','--lockwait','0','--bwlimit','32768','--ionice','7','--tmpdir',str(tmpdir)]"],"name":"dump_argv","source_sha256":"5244bbe02f2fc966e08b6c71ffc8430cedfb66635864e8994f8bcc3a1483cd93"} -PVE270_HOST_MAPPING={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py","file_sha256":"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef","lines":["def host_mapping():"," # Scope of the exception is this observed, protected system ELF pair only."," # PVE modules and private data retain the original single-link reader."," pins={p:t.sha(t.read_secure(Path(p),2*1024**2)[0]) for p in"," ('/usr/share/perl5/PVE/LXC.pm','/usr/share/perl5/PVE/VZDump/LXC.pm')}"," code=('my($m,$u,$g)=PVE::LXC::parse_id_maps({unprivileged=>1,lxc=>[]});'"," 'print JSON::PP->new->canonical->encode({root_uid=>0+$u,root_gid=>0+$g,'"," 'id_map=>[map {[$_->[0],0+$_->[1],0+$_->[2],0+$_->[3]]} @$m]});')"," with PerlPin('/usr/bin/perl','/usr/bin/perl5.40.1') as pin:"," rc,b=pin.run(['-MPVE::LXC','-MJSON::PP','-e',code])"," need(rc==0,'PVE_IDMAP_READ_FAILED')"," for p,h in pins.items():need(t.sha(t.read_secure(Path(p),2*1024**2)[0])==h,'PVE_MAPPING_SOURCE_CHANGED')"," pin.check()"," try:d=json.loads(b)"," except (ValueError,UnicodeError):raise old.PVEError('PVE_IDMAP_JSON') from None"," return validate_mapping(d)"],"name":"host_mapping","source_sha256":"3594394c852f13ba57e3c1ae623a071352d95d2dac35bfba6bb6af73d5783f0a"} -PVE270_VALIDATE_MAPPING={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py","file_sha256":"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef","lines":["def validate_mapping(d):"," need(type(d) is dict and set(d)=={'root_uid','root_gid','id_map'},'IDMAP_SCHEMA')"," need(type(d['root_uid']) is int and type(d['root_gid']) is int,'IDMAP_VALUE')"," need(d['root_uid']==d['root_gid']==100000,'ONLY_DEFAULT_UNPRIVILEGED_IDMAP')"," expect=[['u',0,100000,65536],['g',0,100000,65536]]"," need(type(d['id_map']) is list and len(d['id_map'])==2,'IDMAP_ROWS')"," for row,exp in zip(d['id_map'],expect):"," need(type(row) is list and len(row)==4 and type(row[0]) is str and all(type(n) is int for n in row[1:]) and row==exp,'IDMAP_NONDEFAULT')"," return d['root_uid'],d['root_gid']"],"name":"validate_mapping","source_sha256":"461ec78d3d02e1d590ed62baee4a278976d9737a88f08e4a4030d702a0be1ef3"} -PVE270_CAPTURE_ARCHIVE={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py","file_sha256":"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef","lines":["def capture_archive(argv,destination,cap,seconds,check):"," \"\"\"Same streaming bounds as 265; stderr kept privately, child-only umask=022.\"\"\""," need(type(argv) is list and argv and all(type(x) is str for x in argv),'ARGV')"," need(type(cap) is int and 0=next_check:check();next_check=now+0.5"," for key,_ in sel.select(min(0.1,max(0,deadline-now))):"," b=os.read(key.fileobj.fileno(),65536)"," if not b:sel.unregister(key.fileobj);continue"," if key.fileobj is p.stdout:"," need(total+len(b)<=cap,'ARCHIVE_CAP_REACHED_PARTIAL_RETAINED')"," stream.write_all(fd,b);digest.update(b);total+=len(b)"," else:"," err_total+=len(b);eh.update(b);chunk=b[:max(0,MAX_STDERR-err_kept)]"," if chunk:stream.write_all(efd,chunk);err_kept+=len(chunk)"," need(deadline>time.monotonic(),'PRODUCER_TIMEOUT')"," try:rc=p.wait(timeout=deadline-time.monotonic())"," except subprocess.TimeoutExpired:raise old.PVEError('PRODUCER_TIMEOUT') from None"," need(rc==0,'PRODUCER_RC_FAILED_PARTIAL_RETAINED');need(total>0,'EMPTY_ARCHIVE');check()"," st=os.fstat(fd);named=os.stat(dest.name,dir_fd=parent,follow_symlinks=False)"," need(st.st_dev==initial.st_dev and st.st_ino==initial.st_ino and t.ident(st)==t.ident(named) and st.st_nlink==1 and st.st_size==total,'PRODUCER_FILE_IDENTITY_CHANGED')"," os.fchmod(fd,0o400);os.fsync(fd);os.fsync(parent);good=True"," return {'size':total,'sha256':digest.hexdigest(),'producer_rc':rc,'identity':list(t.ident(os.fstat(fd)))}"," finally:"," if p is not None:"," if p.poll() is None:old.terminate(p)"," p.wait();p.stdout.close();p.stderr.close()"," if sel is not None:sel.close()"," try:"," if fd is not None:os.fsync(fd)"," if efd is not None:os.fsync(efd)"," if owned:"," summary={'process_started':p is not None,'producer_rc':p.returncode if p is not None else None,"," 'capture_success':good,'archive_bytes':total,'stderr_bytes_observed':err_total,"," 'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,"," 'stderr_stream_sha256':eh.hexdigest(),'raw_stderr_exported':False,'child_umask':'0022'}"," t.create(dest.parent/'PRODUCER_PROCESS.json',core.canonical_bytes(summary))"," finally:"," if fd is not None:os.close(fd)"," if efd is not None:os.close(efd)"," os.close(parent)"],"name":"capture_archive","source_sha256":"795afc9f2c9f3ff0691680362771f703506295588e6f6b73dfb7e68addded6e7"} -PVE270_PRODUCE={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py","file_sha256":"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef","lines":["def produce(job,work,tools,guard,*,mapping,seconds=14400,emit=lambda k,v:None):"," need(callable(guard),'GUARD_REQUIRED');guard();old.validate_job(job,int(time.time()));old.validate_tools(tools)"," need(job.get('vmid')==110 and job.get('type')=='lxc' and job.get('config_sha256')==EXPECTED_CFG,'ONLY_ACCEPTED_CT110')"," uid,gid=validate_mapping(mapping)"," work=Path(work);parent=stream.private_dir(work)"," try:need(os.listdir(parent)==[],'PRODUCER_WORKSPACE_NOT_EMPTY')"," finally:os.close(parent)"," # Keep the old orchestration contract: this private placeholder stays empty."," t.make_dir(work/'tmp',exclusive=True)"," scratch=None;complete=False"," try:"," scratch=MappedScratch(gid)"," emit('PVE_TEMP_DIRECTORY',scratch.path);emit('PVE_TEMP_MODE','0710');emit('PVE_TEMP_GID',gid)"," t.create(work/'PVE_TEMP.json',core.canonical_bytes({'path':str(scratch.path),'mode':'0710','uid':0,'gid':gid,'identity':list(scratch.identity)}))"," scratch.probe(uid,work);emit('MAPPED_UID_ACCESS_AND_ISOLATION_PROBE','PASS')"," def free_guard():"," scratch.check()"," for path,reserve,reason in ((work,old.LOCAL_RESERVE,'STAGING_RESERVE_REACHED_PARTIAL_RETAINED'),(scratch.path,256*1024**2,'PVE_TEMP_RESERVE_LOW')):"," v=os.statvfs(path);need(v.f_frsize*v.f_bavail>=reserve,reason)"," free_guard();guard();dest=work/'guest-110.tar.zst'"," result=capture_archive(old.dump_argv(job,tools['vzdump']['path'],scratch.path,int(time.time())),dest,job['archive_cap_bytes'],seconds,free_guard)"," guard();old.validate_tools(tools)"," rc,_=t.bounded_process([tools['zstd']['path'],'--test','--quiet','--',str(dest)],dict(old.ENV),65536,min(seconds,3600))"," need(rc==0,'ARCHIVE_COMPRESSION_TEST_FAILED_RETAINED')"," n,h,identity=stream.hash_file(dest,job['archive_cap_bytes'])"," need(n==result['size'] and h==result['sha256'] and list(identity)==result['identity'],'PRODUCER_READBACK_MISMATCH')"," guard();old.validate_tools(tools);scratch.close(empty_only=True);complete=True;emit('PVE_TEMP_EMPTY_REMOVED','YES')"," return {**result,'path':str(dest),'vmid':110,'type':'lxc','node':job['node'],'config_sha256':job['config_sha256'],"," 'compression_test_ok':True,'restored':False,'state':'PRODUCED_COMPRESSION_CHECKED_NOT_CLOUD_SEALED','local_payload_retained':True}"," finally:"," m=work/'PRODUCER_PROCESS.json'"," if m.exists():"," info=json.loads(t.read_secure(m,65536,private=True)[0])"," emit('VZDUMP_PROCESS_STARTED','YES' if info.get('process_started') else 'NO')"," emit('VZDUMP_PROCESS_RC',info.get('producer_rc'));emit('PRIVATE_STDERR_BYTES',info.get('stderr_bytes_retained'))"," if scratch is not None and not complete:"," emit('PVE_TEMP_RETAINED','YES');scratch.close(empty_only=False)"],"name":"produce","source_sha256":"5278bae09546a659401348335cf2d0834f49d372727a4751245ead6a3aa27a79"} -PVE270_LIVE_GATE={"file":"/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py","file_sha256":"97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef","lines":["def live_gate(job,pvesh_path,pvesh_sha):"," need(job.get('vmid')==110 and job.get('type')=='lxc' and job.get('node')=='pve01' and job.get('config_sha256')==EXPECTED_CFG,'ONLY_ACCEPTED_CT110')"," vals=[]"," for part in ('config','status/current','snapshot'):"," need(t.sha(t.read_secure(Path(pvesh_path),16*1024**2)[0])==pvesh_sha,'PVESH_CHANGED')"," rc,b=t.bounded_process([str(pvesh_path),'get','/nodes/pve01/lxc/110/'+part,'--output-format','json'],dict(old.ENV),262144,30)"," need(rc==0,'CT_GATE_READ_FAILED')"," try:vals.append(json.loads(b))"," except (ValueError,UnicodeError):raise old.PVEError('CT_GATE_JSON') from None"," validate_ct(*vals,job['config_sha256'])"," return True"],"name":"live_gate","source_sha256":"5ec8790c2633c8e576ddecfc04d7878ce7a5ee8ee2de5097dd664245f6621ac0"} -ADAPTER_CONTEXT={"bytes":2989,"file_sha256":"18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3","lines":["11:'pve265.py':'cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be',","12:'guest266.py':'86433bc424d5fa5017c20f7a237c82874b02357a3283660d8a6b0039ef2bc868',","13:'pve270.py':'97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef',","14:'pve282.py':'73c6cb7773eb8e82d1e7ed5ab4733b4afb88f74ae69c09125d0378d6e480e012'}","15:def sha(p):","23: if not p.is_file() or p.is_symlink() or sha(p)!=want:raise RuntimeError('SOURCE_IDENTITY_'+name)","24:def load_graph():","25: import guest266,pve265,pve270,pve282","26: if hasattr(guest266,'dump_argv'):raise RuntimeError('GUEST266_UNEXPECTED_DUMP_ARGV')","27: if not hasattr(pve265,'dump_argv'):raise RuntimeError('PVE265_DUMP_ARGV_MISSING')","28: if getattr(pve270,'old',None) is not pve265:raise RuntimeError('PVE270_OLD_NOT_PVE265')","29: if getattr(pve282,'old',None) is not pve265:raise RuntimeError('PVE282_OLD_NOT_PVE265')","30: if getattr(pve282,'proven',None) is not pve270:raise RuntimeError('PVE282_PROVEN_NOT_PVE270')","31: for n in ('MappedScratch','capture_archive','validate_mapping'):","32: if not hasattr(pve270,n):raise RuntimeError('PVE270_'+n.upper()+'_MISSING')","33: if getattr(pve282,n,None) is not getattr(pve270,n):raise RuntimeError('PVE282_ALIAS_'+n.upper()+'_MISMATCH')","34: return guest266,pve265,pve270,pve282","35:def describe():","36: _,p265,p270,p282=load_graph()","37: funcs={'pve265.dump_argv':p265.dump_argv,'pve265.validate_job':p265.validate_job,'pve265.make_plan':p265.make_plan,'pve270.validate_mapping':p270.validate_mapping,'pve270.capture_archive':p270.capture_archive,'pve270.produce':p270.produce,'pve282.select112':p282.select112,'pve282.produce':p282.produce}","38: return {'schema':1,'bundle':'pve-lxc-adapter-411r1','source_sha256':EXPECTED,'signatures':{k:str(inspect.signature(v)) for k,v in funcs.items()},'owner':{'dump_argv':'pve265','MappedScratch':'pve270','capture_archive':'pve270','validate_mapping':'pve270','pve282.old':'pve265','pve282.proven':'pve270'}}","39:def main():","40: verify_sources(); mode=sys.argv[1] if len(sys.argv)>1 else 'selftest'; d=describe()"],"match_count":10,"state":"OK"} -RETENTION_CLI_FLAGS=["--arg","--argjson","--config","--dirs-only","--immutable","--max-depth","--size-only"] -GFS_CLI_FLAGS=[] -RETENTION_SOURCE_CONTEXT={"bytes":32975,"file_sha256":"8adb6c10f5911f39c53775b89eac3cd1823f1ed34b4caccade5279c213e998a3","lines":["21:REGISTRY_HELPER=\"${HOMELAB_BACKUP_TARGET_REGISTRY_HELPER:-/usr/local/libexec/homelab-backup-target-registry}\"","22:REGISTRY_HELPER_SHA_EXPECTED=c681c44be7557d192d7b453b67e31164237874596168f1d4c78e1e926e2e9cb4","23:GFS_HELPER=\"${HOMELAB_BACKUP_GFS_POLICY_HELPER:-/usr/local/libexec/homelab-backup-gfs-policy}\"","24:GFS_HELPER_SHA_EXPECTED=6b7ec1ab3ee1c540a9113b5620c3b4b5a50de6536f3a069d31b2e1243f23bafa","25:GFS_POLICY=\"${HOMELAB_BACKUP_GFS_POLICY:-/etc/homelab-backup/gfs-retention.json}\"","26:CONTROL_EVIDENCE_ROOT=/var/lib/homelab-backup/control-restore-validation/control-bootstrap","27:[[ -x \"$REGISTRY_HELPER\" && ! -L \"$REGISTRY_HELPER\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=TARGET_REGISTRY_HELPER_MISSING\\n' >&2; exit 69; }","28:[[ \"$(sha256sum \"$REGISTRY_HELPER\"|awk '{print $1}')\" == \"$REGISTRY_HELPER_SHA_EXPECTED\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=TARGET_REGISTRY_HELPER_SHA_DRIFT\\n' >&2; exit 65; }","29:\"$REGISTRY_HELPER\" validate >/dev/null || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=TARGET_REGISTRY_INVALID\\n' >&2; exit 66; }","30:[[ -x \"$GFS_HELPER\" && ! -L \"$GFS_HELPER\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=GFS_POLICY_HELPER_MISSING\\n' >&2; exit 69; }","31:[[ \"$(sha256sum \"$GFS_HELPER\"|awk '{print $1}')\" == \"$GFS_HELPER_SHA_EXPECTED\" ]] || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=GFS_POLICY_HELPER_SHA_DRIFT\\n' >&2; exit 65; }","32:HOMELAB_BACKUP_GFS_POLICY=\"$GFS_POLICY\" \"$GFS_HELPER\" validate >/dev/null || { printf 'GC_STATUS=ERROR|ROOT_CAUSE=GFS_POLICY_INVALID\\n' >&2; exit 66; }","33:GFS_WEEKLY=\"$(HOMELAB_BACKUP_GFS_POLICY=\"$GFS_POLICY\" \"$GFS_HELPER\" weekly-buckets)\"","34:GFS_MONTHLY=\"$(HOMELAB_BACKUP_GFS_POLICY=\"$GFS_POLICY\" \"$GFS_HELPER\" monthly-buckets)\"","35:GFS_CRITICAL_COUNT=\"$(HOMELAB_BACKUP_GFS_POLICY=\"$GFS_POLICY\" \"$GFS_HELPER\" critical-logicals | wc -l)\"","36:VM_KEEP=\"$(\"$REGISTRY_HELPER\" policy-keep VM)\"","37:APP_KEEP=\"$(\"$REGISTRY_HELPER\" policy-keep APP)\"","38:CONTROL_KEEP=\"$(\"$REGISTRY_HELPER\" policy-keep CONTROL)\"","39:MIN_DELETE_AGE_SECONDS=86400","40:SSH_BASE=(-n -o BatchMode=yes -o ConnectTimeout=12 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=[SENSITIVE_PATH] local msg=\"$1\" rc=\"${2:-65}\"; trap - ERR; printf 'GC_STATUS=ERROR|ROOT_CAUSE=%s\\n' \"$msg\" >&2; exit \"$rc\"; }","43:cleanup(){ if [[ -n \"${TMPROOT:-}\" && -d \"$TMPROOT\" ]]; then rm -rf -- \"$TMPROOT\"; fi; }","44:stable_delete_set(){ sed -E 's/\\|age_seconds=[0-9]+$//'; }","45:trap cleanup EXIT","46:","72:strict_state(){","73: local json=\"$1\" logical=\"$2\" generation=\"$3\"","74: jq -e --arg l \"$logical\" --arg g \"$generation\" '.schema==\"homelab-cloud-quorum-payload-v1\" and .logical_id==$l and .generation==$g and .status==\"SEALED\" and .cloud_quorum==2 and .cloud_a_verified==true and .cloud_b_verified==true and .part_hashes_verified==true and .seal_written==true and .cloud_a_seal_verified==true and .cloud_b_seal_verified==true and .local_delete_allowed==true and .local_payload_present==false and .local_cleanup==\"OK\"' <<<\"$json\" >/dev/null","75:}","76:latest_restore_proven(){","121: case \"$status\" in","122: DONE) ;;","123: PLANNED|B_DELETED) count=$((count+1)) ;;","124: *) die \"TX_STATUS_INVALID_$f\" ;;","125: esac","128:}","129:","130:pinned_delete_contract_enabled(){","131: [[ -n \"${HOMELAB_RETENTION_PINNED_DELETE_FILE:-}\" || -n \"${HOMELAB_RETENTION_PINNED_DELETE_SHA256:-}\" ]]","132:}","133:pinned_delete_assert_file(){","134: local f=\"${HOMELAB_RETENTION_PINNED_DELETE_FILE:-}\" expected=\"${HOMELAB_RETENTION_PINNED_DELETE_SHA256:-}\" actual line logical generation owner state_file state_sha count=0","135: [[ -n \"$f\" && -n \"$expected\" ]] || die PINNED_DELETE_CONTRACT_INCOMPLETE 64","136: [[ \"$expected\" =~ ^[0-9a-f]{64}$ ]] || die PINNED_DELETE_SHA_INVALID 64","137: [[ -f \"$f\" && ! -L \"$f\" ]] || die PINNED_DELETE_FILE_UNSAFE 64","138: actual=\"$(sha256sum \"$f\" | awk '{print $1}')\"","139: [[ \"$actual\" == \"$expected\" ]] || die PINNED_DELETE_FILE_SHA_MISMATCH 66","140: while IFS= read -r line; do","141: [[ -n \"$line\" ]] || die PINNED_DELETE_EMPTY_LINE 66","142: logical=\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^logical=/){sub(/^logical=/,\"\",$i);print $i}}' <<<\"$line\")\"","143: generation=\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^generation=/){sub(/^generation=/,\"\",$i);print $i}}' <<<\"$line\")\"","145: state_file=\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^state_file=/){sub(/^state_file=/,\"\",$i);print $i}}' <<<\"$line\")\"","146: state_sha=\"$(awk -F'|' '{for(i=1;i<=NF;i++)if($i~/^state_sha256=/){sub(/^state_sha256=/,\"\",$i);print $i}}' <<<\"$line\")\"","147: [[ \"$line\" == \"DELETE|logical=$logical|generation=$generation|owner=$owner|state_file=$state_file|state_sha256=$state_sha\" ]] || die PINNED_DELETE_LINE_FORMAT_INVALID 66","148: [[ \"$(node_for_logical \"$logical\")\" == \"$owner\" ]] || die \"PINNED_DELETE_OWNER_INVALID_${logical}\" 66","149: safe_generation \"$logical\" \"$generation\" || die \"PINNED_DELETE_GENERATION_INVALID_${logical}\" 66","150: [[ \"$state_file\" == \"$STATE_ROOT/$logical/$generation.json\" ]] || die \"PINNED_DELETE_STATE_PATH_INVALID_${logical}\" 66","151: [[ \"$state_sha\" =~ ^[0-9a-f]{64}$ ]] || die \"PINNED_DELETE_STATE_SHA_INVALID_${logical}\" 66"],"match_count":28,"state":"OK"} -GFS_SOURCE_CONTEXT={"state":"ABSENT"} -POLICY_EVIDENCE={"bytes":1436,"hits":[],"sha256":"e06b7e6285eda2885ef913aa954a70abc7c1d892199a8b7cea2ada98b8edba34","top_keys":["account_failure_domains","accounts","canary","change_id","cloud_retention","failure_policy","local_retention","policy_id","provider","provider_failure_domains","quorum","restore_policy","schema_version"],"top_type":"dict"} -OPS_REPO_EVIDENCE={"branch":{"lines":["main"],"rc":0,"stderr_sha256":null,"stdout_sha256":"6403203dd5a0867eb14d104ee8a73730bd72dd9ad92e78d996a6dba0a5dcfc01"},"current_lifecycle":{"lines":["HEAD:kb/AI_CONTEXT.md:24:110 dns1, 111 dns2, 112 unbound1, 113 unbound2, VM130 edge-vm, VM150 Snikket, VM160 forum-prod, VM170 core-apps/Gitea, VM171 monitoring, VM190 Gitea Actions runner. VM180 and CT200 are retirement candidates only; no blind delete. VM9130 edge-cold-standby stays until timed VM130 DR restore proof.","HEAD:kb/AI_CONTEXT.md:28:Inbound pvepro.ru mail is retired with Null MX. Outbound PHP/XenForo transport is Yandex Cloud Postbox via VM160 msmtp. Credential ref is `postbox_smtp_secret`; its storage metadata is private-facade data and the value never belongs in Git/chat. Five XenForo DBs require individual P0 application acceptance: `xf_codevipe`, `xf_dsmods`, `xf_gamevipe`, `xf_hkmods`, `xf_zakrutim`.","HEAD:kb/AI_CONTEXT_PUBLIC.md:11:The homelab is a three-node Proxmox cluster with dedicated DNS/Unbound guests, EDGE VM, Snikket, forum production, core-apps/Gitea, monitoring and Gitea Actions runner. Retirement candidates and DR standby are not deletion-authorized merely because they are not primary production.","HEAD:kb/AI_CONTEXT_PUBLIC.md:15:CR0083 is merged/closed. Current P0 sequence starts with Git topology preservation, then canonical post-migration state, recovery/backup refresh, VM160/forum acceptance, permanent new-USA SSH hardening, old-USA observation/retirement, and final seal.","HEAD:kb/AI_CONTEXT_PUBLIC.md:19:- Inbound mail is intentionally retired with Null MX; outbound forum mail uses Yandex Cloud Postbox.","HEAD:kb/changes/CR-2026-0086-HANDOFF.md:142:CR0085 should be reviewed/retired separately after CR0086 is established.","HEAD:kb/changes/CR-2026-0087-HANDOFF.md:11:- retired VM170 application/control-plane state is removed.","HEAD:kb/changes/CR-2026-0087-HANDOFF.md:12:- VM171 retired monitoring closure is complete.","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:10:- CMD-1137..1140: VM171 retired Kuma/Prometheus monitoring closure completed and read back.","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:11:- CMD-1141: VM170 retired application payload removed; VM170 itself remains KEEP/CRITICAL as Gitea/core-app host.","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:14:- CMD-1144: retired current registry/backup metadata, stale latest-state/runbooks and orphan Beszel/SOPS current state removed; service registry, dependency map, runbooks and local desired-state regenerated.","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:24:- `/root/homelab-cleanup-backups/CR-2026-0087/cmd-1139-retired-health`","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:26:- `/var/backups/homelab-cleanup/CR-2026-0087/cmd-1141-vm170-retired-payload`","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:29:- `/var/backups/homelab-cleanup/CR-2026-0087/cmd-1144-retired-current-state`","HEAD:kb/changes/CR-2026-0087-IMPLEMENTATION.md:37:`tools/collect_context.py` no longer tracks the retired `homelab-crypto-portfolio-chart-health.timer`; generated context is refreshed from cleaned current state.","HEAD:kb/current/01_CURRENT_STATE.md:12:- old Mailcow/old NetBird server architecture is retired from production; rollback window remains.","HEAD:kb/current/04_P0_NEXT.md:5:3. Canonical post-migration CR including NetBird new USA, Postbox/Null MX, Moldova V3/Gotify, old-USA retirement window and dependencies.","HEAD:kb/private/archive/2026-08-19/MANIFEST.tsv:18:docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md\t1740","HEAD:kb/private/archive/2026-08-19/MANIFEST.tsv:24:docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md\t2504","HEAD:kb/private/archive/2026-08-19/MANIFEST.tsv:29:docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md\t963","HEAD:kb/private/archive/2026-08-19/README_FIRST.md:21:6. `docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md`","HEAD:kb/private/archive/2026-08-19/SHA256SUMS:18:ad3ea70345063e8a13608a83acb4d6a1118533eb6acab22929e0bf1ac20c06af docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md","HEAD:kb/private/archive/2026-08-19/SHA256SUMS:24:c8c11e3c6b8b5d9e2509f975657194944edbc89e483da04f2413224b79084309 docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md","HEAD:kb/private/archive/2026-08-19/SHA256SUMS:29:426a22a970150ff86adbd441a616481fbcedfc1cdb48c5a4976862d747cbcd43 docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md","HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:122:VM180 and CT200 are retirement candidates only, not blind-delete authorization.","HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:153:Inbound email deliberately retired.","HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:256:`/root/retired-mailcow-backups/mailcow-final-offline-20260818T185112Z`","HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:264:Old observer retirement backup:","HEAD:kb/private/archive/2026-08-19/docs/01_CURRENT_AUTHORITATIVE_STATE.md:265:`/root/retired-homelab-dr-observer-20260818T221046Z`","HEAD:kb/private/archive/2026-08-19/docs/02_CLUSTER_TOPOLOGY_AND_INVENTORY.md:74:Known consumers prove these are not currently safe to retire blindly.","HEAD:kb/private/archive/2026-08-19/docs/05_BACKUP_DR_AND_CLOUDS.md:49:Lifecycle = not configured","HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:20:- current mirror policy: verify or formally retire mirror","HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:33:- second independent copy of retired Mailcow archive","HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:92:Retire only with fresh consumer proof:","HEAD:kb/private/archive/2026-08-19/docs/11_OPEN_ISSUES_AND_FUTURE_WORK.md:101:### Retirement projects","HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:1:# CRITICAL KEEP / RETIRE DECISIONS","HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:3:This is a convenience matrix distilled from the historical handbook plus current state. A RETIRE label is not authorization to delete without fresh proof.","HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:16:| VM180 cluster-admin | historical future RETIRE candidate | only after dependency/backup/monitoring cleanup |","HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:18:| CT200 skladchik-mod | historical future RETIRE candidate | preserve required data/monitoring first |","HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:24:| pve01 18788 | KEEP NOW | reader-v3, usage proof before retirement |","HEAD:kb/private/archive/2026-08-19/docs/17_CLOUDRU_CURRENT.md:18:lifecycle: absent","HEAD:kb/private/archive/2026-08-19/docs/18_P0_CLOSEOUT_MASTER_PLAN_2026-08-19.md:35:- old NetBird server retirement","HEAD:kb/private/archive/2026-08-19/docs/18_P0_CLOSEOUT_MASTER_PLAN_2026-08-19.md:36:- Mailcow retirement","HEAD:kb/private/archive/2026-08-19/docs/18_P0_CLOSEOUT_MASTER_PLAN_2026-08-19.md:42:- AlexHost retirement/rollback window","HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:1:# MAILCOW RETIREMENT / POSTBOX / FORUMS \u2014 CURRENT RECORD","HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:8:18 containers before retirement.","HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:30:## Retirement","HEAD:kb/private/archive/2026-08-19/docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md:53:`/root/retired-mailcow-backups/mailcow-final-offline-20260818T185112Z`","HEAD:kb/private/archive/2026-08-19/docs/22_MOLDOVA_HEALTHCHECK_GOTIFY_2026-08-18.md:14:Old checker referenced retired Mailcow/old NetBird IP and caused false failures.","HEAD:kb/private/archive/2026-08-19/docs/22_MOLDOVA_HEALTHCHECK_GOTIFY_2026-08-18.md:48:Old USA observer had been converted to Gotify-only before retirement.","HEAD:kb/private/archive/2026-08-19/docs/22_MOLDOVA_HEALTHCHECK_GOTIFY_2026-08-18.md:103:`/root/retired-homelab-dr-observer-20260818T221046Z`","HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:20:- current mirror policy: verify or formally retire mirror","HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:33:- second independent copy of retired Mailcow archive","HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:92:Retire only with fresh consumer proof:","HEAD:kb/private/archive/2026-08-19/docs/24_GLOBAL_BACKLOG_MASTER_2026-08-19.md:101:### Retirement projects","HEAD:kb/private/archive/2026-08-19/docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md:1:# ALEXHOST RETIREMENT / BILLING STATE \u2014 2026-08-19","HEAD:kb/private/archive/2026-08-19/docs/27_SECURITY_ACCESS_CURRENT_DELTA_2026-08-19.md:12:Lifecycle:","HEAD:kb/private/archive/2026-08-19/docs/27_SECURITY_ACCESS_CURRENT_DELTA_2026-08-19.md:14:- after accepted old-USA shutdown/retirement:","HEAD:kb/private/archive/2026-08-19/machine/current_state.json:108: \"lifecycle\": \"NOT_CONFIGURED\",","HEAD:kb/private/archive/2026-08-19/machine/current_state.yaml:89: new_usa_path: \"/root/retired-mailcow-backups/mailcow-final-offline-20260818T185112Z\"","HEAD:kb/private/source/source_manifest.json:83: \"path\": \"docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md\",","HEAD:kb/private/source/source_manifest.json:98: \"path\": \"docs/26_ALEXHOST_RETIREMENT_STATE_2026-08-19.md\",","HEAD:kb/private/source/source_manifest.json:113: \"path\": \"docs/21_MAILCOW_RETIREMENT_POSTBOX_FORUMS_2026-08-18.md\",","HEAD:kb/runbooks/02_PROXMOX.md:12:Before deletion/retirement, prove consumers and backup/restore path. VM9130 remains protected until timed VM130 DR restore proof.","HEAD:kb/runbooks/05_FORUMS_MAIL.md:9:Null MX means inbound mail is intentionally retired; do not \u201crepair\u201d old Mailcow MX/DNS as if outage without checking current policy.","HEAD:kb/secrets/registry.json:92: \"lifecycle\": \"Remove after old-USA retirement accepted and corresponding authorized_keys line no longer needed.\""],"rc":0,"stderr_sha256":null,"stdout_sha256":"fefced8de60a5efa9488a0bcc961ca0d75d90bc2f411e26a7fe40d4e0b106c78"},"current_vm200":{"lines":["HEAD:kb/inventory/guests.json:136: \"name\": \"skladchik-mod\",","HEAD:kb/inventory/guests.json:143: \"role\": \"skladchik-mod: moderator v2 + PostgreSQL\",","HEAD:kb/private/archive/2026-08-19/docs/02_CLUSTER_TOPOLOGY_AND_INVENTORY.md:42:| 200 | skladchik-mod | lxc | pve03 | running | [PRIVATE_IP] | 6144 MiB | 39.1 GiB | skladchik-mod: moderator v2 + PostgreSQL |","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:230:## VM/LXC 200 \u2014 skladchik-mod","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:232:Role: skladchik-mod: moderator v2 + PostgreSQL.","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:235:- `skladchik-moderator-v2-collector.service`","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:236:- `skladchik-moderator-v2-collector.timer`","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:237:- `skladchik-moderator-v2-rules.service`","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:238:- `skladchik-moderator-v2-rules.timer`","HEAD:kb/private/archive/2026-08-19/docs/03_SERVICE_CATALOG.md:239:- `skladchik-moderator-v2-web.service`","HEAD:kb/private/archive/2026-08-19/docs/15_CRITICAL_KEEP_RETIRE_DECISIONS.md:18:| CT200 skladchik-mod | historical future RETIRE candidate | preserve required data/monitoring first |","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1929: \"name\": \"skladchik-mod\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1941: \"skladchik-moderator-v2-web.service\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1993: \"unit\": \"skladchik-moderator-v2-collector.timer\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:1997: \"unit\": \"skladchik-moderator-v2-rules.timer\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2012: \"skladchik-moderator-v2-collector.service\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2013: \"skladchik-moderator-v2-collector.timer\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2014: \"skladchik-moderator-v2-rules.service\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2015: \"skladchik-moderator-v2-rules.timer\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2016: \"skladchik-moderator-v2-web.service\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2031: \"role\": \"skladchik-mod: moderator v2 + PostgreSQL\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.json:2038: \"name\": \"skladchik-mod\",","HEAD:kb/private/archive/2026-08-19/machine/cluster_inventory.tsv:13:200\tskladchik-mod\tlxc\tpve03\trunning\t[PRIVATE_IP]\t6144\t39.1\tskladchik-mod: moderator v2 + PostgreSQL","HEAD:observed/cluster-guests.json:238: \"id\": \"lxc/200\",","HEAD:observed/cluster-guests.json:244: \"name\": \"skladchik-mod\","],"rc":0,"stderr_sha256":null,"stdout_sha256":"df20c2a29261d45b0b381d76e521bf77e9564403622c73fc1790fba39ba4d42d"},"head":{"lines":["d5e2ef5639398a762283e47143c17b494f8ed579"],"rc":0,"stderr_sha256":null,"stdout_sha256":"baa4912ce1befe1c70ce681a7e9110152b3c894c8b36ed9880013efd7b70cb29"},"history":{"lines":[],"rc":0,"stderr_sha256":null,"stdout_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},"refs":{"refs/heads/cr-2026-0035-skladchik-moderator-ct200":{"diff_names":{"lines":["D\t.gitea/workflows/validate-kb.yml","M\tACTIVE_CHANGES.md","M\tAGENTS.md","M\tCURRENT_CONTEXT.md","D\tKB_START_HERE.md","M\tREADME.md","D\tchanges/CR-2026-0018/acceptance.json","D\tchanges/CR-2026-0018/caller-inventory-requirements.md","D\tchanges/CR-2026-0018/design.md","A\tchanges/CR-2026-0018/evidence.md","D\tchanges/CR-2026-0018/execution-contract.md","A\tchanges/CR-2026-0018/plan.json","D\tchanges/CR-2026-0018/plan.md","D\tchanges/CR-2026-0018/regression-cases-draft.json","D\tchanges/CR-2026-0018/request.json","D\tchanges/CR-2026-0018/review-decision.md","M\tchanges/CR-2026-0018/risk.md","M\tchanges/CR-2026-0018/rollback.md","A\tchanges/CR-2026-0018/task-package.sha256","D\tchanges/CR-2026-0018/task-reference.md","M\tchanges/CR-2026-0018/tests.md","D\tchanges/CR-2026-0018/threat-model.md","A\tchanges/CR-2026-0019/evidence.md","A\tchanges/CR-2026-0019/plan.json","A\tchanges/CR-2026-0019/risk.md","A\tchanges/CR-2026-0019/rollback.md","A\tchanges/CR-2026-0019/source-freeze.sha256","A\tchanges/CR-2026-0019/task-package.sha256","A\tchanges/CR-2026-0019/tests.md","A\tchanges/CR-2026-0026/design-package.sha256","A\tchanges/CR-2026-0026/discovery.md","A\tchanges/CR-2026-0026/implementation.md","A\tchanges/CR-2026-0026/plan.json","A\tchanges/CR-2026-0026/risk.md","A\tchanges/CR-2026-0026/rollback.md","A\tchanges/CR-2026-0026/source-provenance.tsv","A\tchanges/CR-2026-0026/task-package.sha256","A\tchanges/CR-2026-0026/tests.md","A\tchanges/CR-2026-0027/design-package.sha256","A\tchanges/CR-2026-0027/discovery.md","A\tchanges/CR-2026-0027/implementation.md","A\tchanges/CR-2026-0027/plan.json","A\tchanges/CR-2026-0027/risk.md","A\tchanges/CR-2026-0027/rollback.md","A\tchanges/CR-2026-0027/source-provenance.tsv","A\tchanges/CR-2026-0027/task-package.sha256","A\tchanges/CR-2026-0027/tests.md","A\tchanges/CR-2026-0028/design-package.sha256","A\tchanges/CR-2026-0028/discovery.md","A\tchanges/CR-2026-0028/implementation.md","A\tchanges/CR-2026-0028/plan.json","A\tchanges/CR-2026-0028/risk.md","A\tchanges/CR-2026-0028/rollback.md","A\tchanges/CR-2026-0028/source-provenance.tsv","A\tchanges/CR-2026-0028/task-package.sha256","A\tchanges/CR-2026-0028/tests.md","A\tchanges/CR-2026-0029/design-package.sha256","A\tchanges/CR-2026-0029/discovery.md","A\tchanges/CR-2026-0029/implementation.md","A\tchanges/CR-2026-0029/plan.json","A\tchanges/CR-2026-0029/risk.md","A\tchanges/CR-2026-0029/rollback.md","A\tchanges/CR-2026-0029/source-provenance.tsv","A\tchanges/CR-2026-0029/task-package.sha256","A\tchanges/CR-2026-0029/tests.md","A\tchanges/CR-2026-0030/design-package.sha256","A\tchanges/CR-2026-0030/discovery.md","A\tchanges/CR-2026-0030/implementation.md","A\tchanges/CR-2026-0030/plan.json","A\tchanges/CR-2026-0030/risk.md","A\tchanges/CR-2026-0030/rollback.md","A\tchanges/CR-2026-0030/source-provenance.tsv","A\tchanges/CR-2026-0030/task-package.sha256","A\tchanges/CR-2026-0030/tests.md","A\tchanges/CR-2026-0031/design-package.sha256","A\tchanges/CR-2026-0031/discovery.md","A\tchanges/CR-2026-0031/implementation.md","A\tchanges/CR-2026-0031/risk.md","A\tchanges/CR-2026-0031/source-provenance.tsv","A\tchanges/CR-2026-0031/task-package.sha256","A\tchanges/CR-2026-0031/tests.md","A\tchanges/CR-2026-0032/README.md","A\tchanges/CR-2026-0032/design-package.sha256","A\tchanges/CR-2026-0032/task-package.sha256","A\tchanges/CR-2026-0033/README.md","A\tchanges/CR-2026-0033/design-package.sha256","A\tchanges/CR-2026-0033/task-package.sha256","A\tchanges/CR-2026-0034/README.md","A\tchanges/CR-2026-0034/design-package.sha256","A\tchanges/CR-2026-0034/task-package.sha256","A\tchanges/CR-2026-0035/discovery.md","A\tchanges/CR-2026-0035/implementation.md","A\tchanges/CR-2026-0035/package.sha256","A\tchanges/CR-2026-0035/risk.md","A\tchanges/CR-2026-0035/source-provenance.tsv","A\tchanges/CR-2026-0035/tests.md","D\tchanges/CR-2026-0078/task-package.sha256","D\tchanges/CR-2026-0079/README.md","D\tchanges/CR-2026-0079/mail-pvepro-dr-observer-source.tar.gz","D\tchanges/CR-2026-0079/task-package.sha256","D\tchanges/CR-2026-0080/task-package.sha256","D\tchanges/CR-2026-0081/home-forward-retire-package.sha256","D\tchanges/CR-2026-0081/turn-dns-retire-package.sha256","D\tchanges/CR-2026-0083/README.md","D\tchanges/CR-2026-0083/gitea-edge-publisher-v3-deploy-v1.tar.gz","D\tchanges/CR-2026-0083/gitea-edge-publisher-v3-source-v1.tar.gz","D\tchanges/CR-2026-0083/source-package.sha256","D\tdeploy/gitea-edge-publisher-v3/MANIFEST.sha256","D\tdeploy/gitea-edge-publisher-v3/deploy.sh","D\tdeploy/gitea-edge-publisher-v3/nginx/git-read-access-log-format.conf","D\tdeploy/gitea-edge-publisher-v3/nginx/git-read-server-observer.conf","D\tdeploy/gitea-edge-publisher-v3/patch_vhost.py","D\tdeploy/gitea-edge-publisher-v3/payload/homelab-gitea-publisher-v3","D\tdeploy/gitea-edge-publisher-v3/payload/homelab-oai-searchbot-observer","D\tdeploy/gitea-edge-publisher-v3/payload/homelab-oai-searchbot-ranges","D\tdeploy/gitea-edge-publisher-v3/rollback.sh","D\tdeploy/gitea-edge-publisher-v3/selftest.sh","D\tdeploy/gitea-edge-publisher-v3/systemd/homelab-gitea-publisher-v3.service","D\tdeploy/gitea-edge-publisher-v3/systemd/homelab-gitea-publisher-v3.timer","D\tdeploy/gitea-edge-publisher-v3/systemd/homelab-oai-searchbot-observer.service"],"rc":0,"stderr_sha256":null,"stdout_sha256":"9f24c0031ba6ccee22a76aee6935c5ff9da440b743eb9428ba38332195f1e1e5"},"exists":true,"vm200":{"lines":["refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.","refs/heads/cr-2026-0035-skladchik-moderator-ct200:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-freshness-probe:12: memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) printf 'app-%s\\n' \"$1\" ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-queue:9:ALL_APPS=(memos skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-queue:10:MIGRATE_APPS=(skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-queue:84: case \"$a\" in memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) ;; *) die \"APP_NOT_ALLOWED_$a\" 64 ;; esac","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:72: skladchik-moderator-assistant) echo app-skladchik-moderator-assistant ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:85: skladchik-moderator-assistant) echo pve01 ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:173: started=\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"; new_capture_paths skladchik-moderator-assistant \"$gen\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:174: mkdir -p \"$CAPTURE/skladchik-moderator-assistant/var-lib\" \"$CAPTURE/skladchik-moderator-assistant/opt\" \"$CAPTURE/skladchik-moderator-assistant/systemd\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:175: [[ -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ]] || die MODERATOR_DB_MISSING 66","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:176: sqlite3 /var/lib/skladchik-moderator-assistant/state.sqlite3 \".backup '$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3'\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:177: chown --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:178: chmod --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:179: touch -r /var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:180: [[ \"$(sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\" 'PRAGMA integrity_check;'|tail -n1)\" == ok ]] || die MODERATOR_DB_BACKUP_INVALID 70","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:181: cp -a /opt/skladchik-moderator-assistant/. \"$CAPTURE/skladchik-moderator-assistant/opt/\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:182: [[ -f /etc/systemd/system/skladchik-moderator-assistant.service ]] && cp -a /etc/systemd/system/skladchik-moderator-assistant.service \"$CAPTURE/skladchik-moderator-assistant/systemd/\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:183: dbsha=\"$(sha256sum \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"|awk '{print $1}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:184: manifest_tree \"$CAPTURE/skladchik-moderator-assistant\" \"$CAPTURE/skladchik-moderator-assistant/files.sha256\"; treesha=\"$(sha256sum \"$CAPTURE/skladchik-moderator-assistant/files.sha256\"|awk '{print $1}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:186: comps=\"$(jq -n --arg a \"$dbsha\" --arg b \"$treesha\" '{database:{path:\"skladchik-moderator-assistant/var-lib/state.sqlite3\",sha256:$a},files_manifest:{path:\"skladchik-moderator-assistant/files.sha256\",sha256:$b}}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:187: write_binding \"$CAPTURE/app-generation.json\" app-skladchik-moderator-assistant \"$gen\" skladchik-moderator-assistant \"$started\" \"$completed\" \"\" \"\" \"$comps\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:358: skladchik-moderator-assistant) capture_moderator \"$gen\" ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:433: skladchik-moderator-assistant)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:434: db=\"$ex/skladchik-moderator-assistant/var-lib/state.sqlite3\"; [[ \"$(sqlite3 \"$db\" 'PRAGMA integrity_check;'|tail -n1)\" == ok ]] || die MODERATOR_RESTORE_INTEGRITY_FAILED 70","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:436: (cd \"$ex/skladchik-moderator-assistant\"; sha256sum -c files.sha256 >/dev/null)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:437: find \"$ex/skladchik-moderator-assistant/opt\" -type f -name '*.py' -print0 | xargs -0 -r python3 -m py_compile","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-cloud-quorum-v1/assets/runtime/homelab-app-cloud-quorum-worker:624: skladchik-moderator-assistant) test -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-freshness-probe:12: memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) printf 'app-%s\\n' \"$1\" ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-queue:9:ALL_APPS=(memos skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-queue:10:MIGRATE_APPS=(skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-queue:84: case \"$a\" in memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) ;; *) die \"APP_NOT_ALLOWED_$a\" 64 ;; esac","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:72: skladchik-moderator-assistant) echo app-skladchik-moderator-assistant ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:85: skladchik-moderator-assistant) echo pve01 ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:173: started=\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"; new_capture_paths skladchik-moderator-assistant \"$gen\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:174: mkdir -p \"$CAPTURE/skladchik-moderator-assistant/var-lib\" \"$CAPTURE/skladchik-moderator-assistant/opt\" \"$CAPTURE/skladchik-moderator-assistant/systemd\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:175: [[ -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ]] || die MODERATOR_DB_MISSING 66","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:176: sqlite3 /var/lib/skladchik-moderator-assistant/state.sqlite3 \".backup '$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3'\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:177: chown --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:178: chmod --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:179: touch -r /var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:180: [[ \"$(sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\" 'PRAGMA integrity_check;'|tail -n1)\" == ok ]] || die MODERATOR_DB_BACKUP_INVALID 70","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:181: cp -a /opt/skladchik-moderator-assistant/. \"$CAPTURE/skladchik-moderator-assistant/opt/\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:182: [[ -f /etc/systemd/system/skladchik-moderator-assistant.service ]] && cp -a /etc/systemd/system/skladchik-moderator-assistant.service \"$CAPTURE/skladchik-moderator-assistant/systemd/\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:183: dbsha=\"$(sha256sum \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"|awk '{print $1}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:184: manifest_tree \"$CAPTURE/skladchik-moderator-assistant\" \"$CAPTURE/skladchik-moderator-assistant/files.sha256\"; treesha=\"$(sha256sum \"$CAPTURE/skladchik-moderator-assistant/files.sha256\"|awk '{print $1}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:186: comps=\"$(jq -n --arg a \"$dbsha\" --arg b \"$treesha\" '{database:{path:\"skladchik-moderator-assistant/var-lib/state.sqlite3\",sha256:$a},files_manifest:{path:\"skladchik-moderator-assistant/files.sha256\",sha256:$b}}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:187: write_binding \"$CAPTURE/app-generation.json\" app-skladchik-moderator-assistant \"$gen\" skladchik-moderator-assistant \"$started\" \"$completed\" \"\" \"\" \"$comps\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:358: skladchik-moderator-assistant) capture_moderator \"$gen\" ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:433: skladchik-moderator-assistant)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:434: db=\"$ex/skladchik-moderator-assistant/var-lib/state.sqlite3\"; [[ \"$(sqlite3 \"$db\" 'PRAGMA integrity_check;'|tail -n1)\" == ok ]] || die MODERATOR_RESTORE_INTEGRITY_FAILED 70","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:436: (cd \"$ex/skladchik-moderator-assistant\"; sha256sum -c files.sha256 >/dev/null)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:437: find \"$ex/skladchik-moderator-assistant/opt\" -type f -name '*.py' -print0 | xargs -0 -r python3 -m py_compile","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-bootstrap-configs-source-v1/assets/runtime/homelab-app-cloud-quorum-worker:624: skladchik-moderator-assistant) test -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-freshness-probe:12: memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) printf 'app-%s\\n' \"$1\" ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-queue:9:ALL_APPS=(memos skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-queue:10:MIGRATE_APPS=(skladchik-moderator-assistant filebrowser skladchik-reports-monitor immich hbarhub scrutiny)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-queue:84: case \"$a\" in memos|skladchik-moderator-assistant|filebrowser|skladchik-reports-monitor|immich|hbarhub|scrutiny) ;; *) die \"APP_NOT_ALLOWED_$a\" 64 ;; esac","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:72: skladchik-moderator-assistant) echo app-skladchik-moderator-assistant ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:85: skladchik-moderator-assistant) echo pve01 ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:173: started=\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"; new_capture_paths skladchik-moderator-assistant \"$gen\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:174: mkdir -p \"$CAPTURE/skladchik-moderator-assistant/var-lib\" \"$CAPTURE/skladchik-moderator-assistant/opt\" \"$CAPTURE/skladchik-moderator-assistant/systemd\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:175: [[ -s /var/lib/skladchik-moderator-assistant/state.sqlite3 ]] || die MODERATOR_DB_MISSING 66","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:176: sqlite3 /var/lib/skladchik-moderator-assistant/state.sqlite3 \".backup '$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3'\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:177: chown --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:178: chmod --reference=/var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:179: touch -r /var/lib/skladchik-moderator-assistant/state.sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:180: [[ \"$(sqlite3 \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\" 'PRAGMA integrity_check;'|tail -n1)\" == ok ]] || die MODERATOR_DB_BACKUP_INVALID 70","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:181: cp -a /opt/skladchik-moderator-assistant/. \"$CAPTURE/skladchik-moderator-assistant/opt/\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:182: [[ -f /etc/systemd/system/skladchik-moderator-assistant.service ]] && cp -a /etc/systemd/system/skladchik-moderator-assistant.service \"$CAPTURE/skladchik-moderator-assistant/systemd/\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:183: dbsha=\"$(sha256sum \"$CAPTURE/skladchik-moderator-assistant/var-lib/state.sqlite3\"|awk '{print $1}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:184: manifest_tree \"$CAPTURE/skladchik-moderator-assistant\" \"$CAPTURE/skladchik-moderator-assistant/files.sha256\"; treesha=\"$(sha256sum \"$CAPTURE/skladchik-moderator-assistant/files.sha256\"|awk '{print $1}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:186: comps=\"$(jq -n --arg a \"$dbsha\" --arg b \"$treesha\" '{database:{path:\"skladchik-moderator-assistant/var-lib/state.sqlite3\",sha256:$a},files_manifest:{path:\"skladchik-moderator-assistant/files.sha256\",sha256:$b}}')\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:187: write_binding \"$CAPTURE/app-generation.json\" app-skladchik-moderator-assistant \"$gen\" skladchik-moderator-assistant \"$started\" \"$completed\" \"\" \"\" \"$comps\"","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:358: skladchik-moderator-assistant) capture_moderator \"$gen\" ;;","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:433: skladchik-moderator-assistant)","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:434: db=\"$ex/skladchik-moderator-assistant/var-lib/state.sqlite3\"; [[ \"$(sqlite3 \"$db\" 'PRAGMA integrity_check;'|tail -n1)\" == ok ]] || die MODERATOR_RESTORE_INTEGRITY_FAILED 70","refs/heads/cr-2026-0035-skladchik-moderator-ct200:tasks/backup-control-final-generation-v1/assets/runtime/homelab-app-cloud-quorum-worker:436: (cd \"$ex/skladchik-moderator-assistant\"; sha256sum -c files.sha256 >/dev/null)"],"rc":0,"stderr_sha256":null,"stdout_sha256":"68d1d931e6d4c48dd15ac5faeb8feddb0548018245d16997d7c486f29c56d355"}},"refs/heads/cr-2026-0058-legacy-backup-target-retirement":{"diff_names":{"lines":["D\t.gitea/workflows/validate-kb.yml","M\tACTIVE_CHANGES.md","M\tAGENTS.md","M\tCURRENT_CONTEXT.md","D\tKB_START_HERE.md","M\tREADME.md","D\tchanges/CR-2026-0018/acceptance.json","D\tchanges/CR-2026-0018/caller-inventory-requirements.md","D\tchanges/CR-2026-0018/design.md","A\tchanges/CR-2026-0018/evidence.md","D\tchanges/CR-2026-0018/execution-contract.md","A\tchanges/CR-2026-0018/plan.json","D\tchanges/CR-2026-0018/plan.md","D\tchanges/CR-2026-0018/regression-cases-draft.json","D\tchanges/CR-2026-0018/request.json","D\tchanges/CR-2026-0018/review-decision.md","M\tchanges/CR-2026-0018/risk.md","M\tchanges/CR-2026-0018/rollback.md","A\tchanges/CR-2026-0018/task-package.sha256","D\tchanges/CR-2026-0018/task-reference.md","M\tchanges/CR-2026-0018/tests.md","D\tchanges/CR-2026-0018/threat-model.md","A\tchanges/CR-2026-0019/evidence.md","A\tchanges/CR-2026-0019/plan.json","A\tchanges/CR-2026-0019/risk.md","A\tchanges/CR-2026-0019/rollback.md","A\tchanges/CR-2026-0019/source-freeze.sha256","A\tchanges/CR-2026-0019/task-package.sha256","A\tchanges/CR-2026-0019/tests.md","A\tchanges/CR-2026-0026/design-package.sha256","A\tchanges/CR-2026-0026/discovery.md","A\tchanges/CR-2026-0026/implementation.md","A\tchanges/CR-2026-0026/plan.json","A\tchanges/CR-2026-0026/risk.md","A\tchanges/CR-2026-0026/rollback.md","A\tchanges/CR-2026-0026/source-provenance.tsv","A\tchanges/CR-2026-0026/task-package.sha256","A\tchanges/CR-2026-0026/tests.md","A\tchanges/CR-2026-0027/design-package.sha256","A\tchanges/CR-2026-0027/discovery.md","A\tchanges/CR-2026-0027/implementation.md","A\tchanges/CR-2026-0027/plan.json","A\tchanges/CR-2026-0027/risk.md","A\tchanges/CR-2026-0027/rollback.md","A\tchanges/CR-2026-0027/source-provenance.tsv","A\tchanges/CR-2026-0027/task-package.sha256","A\tchanges/CR-2026-0027/tests.md","A\tchanges/CR-2026-0028/design-package.sha256","A\tchanges/CR-2026-0028/discovery.md","A\tchanges/CR-2026-0028/implementation.md","A\tchanges/CR-2026-0028/plan.json","A\tchanges/CR-2026-0028/risk.md","A\tchanges/CR-2026-0028/rollback.md","A\tchanges/CR-2026-0028/source-provenance.tsv","A\tchanges/CR-2026-0028/task-package.sha256","A\tchanges/CR-2026-0028/tests.md","A\tchanges/CR-2026-0029/design-package.sha256","A\tchanges/CR-2026-0029/discovery.md","A\tchanges/CR-2026-0029/implementation.md","A\tchanges/CR-2026-0029/plan.json","A\tchanges/CR-2026-0029/risk.md","A\tchanges/CR-2026-0029/rollback.md","A\tchanges/CR-2026-0029/source-provenance.tsv","A\tchanges/CR-2026-0029/task-package.sha256","A\tchanges/CR-2026-0029/tests.md","A\tchanges/CR-2026-0030/design-package.sha256","A\tchanges/CR-2026-0030/discovery.md","A\tchanges/CR-2026-0030/implementation.md","A\tchanges/CR-2026-0030/plan.json","A\tchanges/CR-2026-0030/risk.md","A\tchanges/CR-2026-0030/rollback.md","A\tchanges/CR-2026-0030/source-provenance.tsv","A\tchanges/CR-2026-0030/task-package.sha256","A\tchanges/CR-2026-0030/tests.md","A\tchanges/CR-2026-0031/design-package.sha256","A\tchanges/CR-2026-0031/discovery.md","A\tchanges/CR-2026-0031/implementation.md","A\tchanges/CR-2026-0031/risk.md","A\tchanges/CR-2026-0031/source-provenance.tsv","A\tchanges/CR-2026-0031/task-package.sha256","A\tchanges/CR-2026-0031/tests.md","A\tchanges/CR-2026-0032/README.md","A\tchanges/CR-2026-0032/design-package.sha256","A\tchanges/CR-2026-0032/task-package.sha256","A\tchanges/CR-2026-0033/README.md","A\tchanges/CR-2026-0033/design-package.sha256","A\tchanges/CR-2026-0033/task-package.sha256","A\tchanges/CR-2026-0034/README.md","A\tchanges/CR-2026-0034/design-package.sha256","A\tchanges/CR-2026-0034/task-package.sha256","A\tchanges/CR-2026-0035/discovery.md","A\tchanges/CR-2026-0035/implementation.md","A\tchanges/CR-2026-0035/package.sha256","A\tchanges/CR-2026-0035/risk.md","A\tchanges/CR-2026-0035/source-provenance.tsv","A\tchanges/CR-2026-0035/tests.md","A\tchanges/CR-2026-0036/discovery.md","A\tchanges/CR-2026-0036/implementation.md","A\tchanges/CR-2026-0036/package.sha256","A\tchanges/CR-2026-0036/risk.md","A\tchanges/CR-2026-0036/source-provenance.tsv","A\tchanges/CR-2026-0036/tests.md","A\tchanges/CR-2026-0046/discovery.md","A\tchanges/CR-2026-0046/implementation.md","A\tchanges/CR-2026-0046/risk.md","A\tchanges/CR-2026-0046/source-provenance.tsv","A\tchanges/CR-2026-0046/task-package.sha256","A\tchanges/CR-2026-0046/tests.md","A\tchanges/CR-2026-0047/task-package.sha256","A\tchanges/CR-2026-0048/discovery.md","A\tchanges/CR-2026-0048/implementation.md","A\tchanges/CR-2026-0048/risk.md","A\tchanges/CR-2026-0048/source-provenance.tsv","A\tchanges/CR-2026-0048/task-package.sha256","A\tchanges/CR-2026-0048/tests.md","A\tchanges/CR-2026-0049/discovery.md","A\tchanges/CR-2026-0049/implementation.md","A\tchanges/CR-2026-0049/risk.md","A\tchanges/CR-2026-0049/source-provenance.tsv","A\tchanges/CR-2026-0049/task-package.sha256"],"rc":0,"stderr_sha256":null,"stdout_sha256":"40ecc0852c5589b22a435e26bbcf5702ae59069739901be6f22734bf008538f1"},"exists":true,"vm200":{"lines":["refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:12:- Recovery after the initial external-network timeout uses a dedicated `skladchik-moderator-v2-edge-egress-v1` task: CT200 alone uses edge-vm `[PRIVATE_IP]` as its default gateway; edge-vm NATs only `[PRIVATE_IP]/32` into its already-existing NetBird `wt0` default exit (table 7120). No NetBird management policy is changed.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:26:Authenticated section evidence on 2026-08-12 showed 107 `discussionListItem` nodes, 106 `PreviewTooltip` markers and 517 root-relative `threads/...` hrefs. `skladchik-moderator-v2-xf1-parser-hotfix-v1` overlays only `forum.py` and `ads.py`, preserving XF2 support while adding XF1 listing/topic/message/search parsing and root-relative URL resolution. Cookie onboarding is fail-closed on the parser hotfix seal and exact installed module SHA values.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:42:The first controlled cookie apply proved the edge-vm source jar before mutation, installed it, then failed only at the v2 `auth-check`; the apply error path removed the CT200 cookie, disabled collector/competitor timers, and removed transient pve03 staging. The divergence was between two authentication classifiers: edge-vm proves the moderator session by authenticated XenForo 1 `discussionListItem` rows, while v2 still downgraded the same cookie-backed section using a text-only login heuristic. `skladchik-moderator-v2-auth-classification-hotfix-v1` preserves the sealed XF1 parser and changes only section authentication classification: a cookie-backed section that parses canonical topic rows is positive auth evidence. This is bounded by the already-observed public response yielding zero rows ","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:54:The authenticated bootstrap reached 104 listed topics and 40 detailed topics but produced zero analyses because every analyzed detail failed at `stage_history.stage = %s` with PostgreSQL `text = bytea`. The application connection inherited `SQL_ASCII`, so Psycopg returned text values as Python bytes and adapted the fetched stage back as `bytea` on the next parameterized query. The fix is at the connection boundary, not an SQL cast: `skladchik-moderator-v2-db-text-encoding-hotfix-v1` pins Psycopg `client_encoding=UTF8`, proves the baseline bytes failure against existing data, then performs a pre-mutation UTF8 probe across every existing app-facing text column and the exact formerly failing stage-history query; apply/verify repeat that proof through the installed module. No schema or data rewr","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:58:The post-cookie health failure after successful authenticated collection (104 listed topics, 17 analyses in the triggering run; 65 analyses persisted overall) was isolated to rule state. The formatting-rule fetch inherited the moderator cookie and was redirected to XenForo `/login/two-step`, creating a non-approved rule-source revision. Rule pages are public policy sources, so `skladchik-moderator-v2-rules-public-sync-hotfix-v1` fetches them through an independent cookie-free Requests session and requires the redirected final URL to preserve the expected rule thread id. Before mutation, the live dry-run requires each current public content hash to already exist as an explicitly approved historical source; a genuinely new rule revision therefore still stops for manual review and is never auto","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:62:The final cookie bootstrap exposed a collector-only SQL defect after all 104 section topics had already been detailed: `global_search_hits` used `ON CONFLICT DO UPDATE` without the unique-key inference target, so PostgreSQL rejected every whole-site duplicate-search upsert for the remaining four topics. Because detail state is committed before duplicate search and analysis, those topics then became ineligible for another detail fetch for two days. `skladchik-moderator-v2-collector-resume-hotfix-v1` fixes the upsert against the existing `UNIQUE(source_topic_id,query_kind,query_text,hit_url)` key and adds a cached-detail analysis backlog that retries topics whose latest committed detail has no analysis at or after that detail timestamp. Its dry-run executes the corrected upsert twice inside a ","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:70:After cookie onboarding is SEALED and current v2 health/timers are re-proven, `skladchik-moderator-v2-old-mvp-retirement-v1` retires only the legacy pve01 operational service. The task pins the exact legacy unit/app/rules bytes and version, captures root-only rollback copies, disables/stops the service, removes `/etc/systemd/system/skladchik-moderator-assistant.service` and `/opt/skladchik-moderator-assistant`, and preserves `/var/lib/skladchik-moderator-assistant` unchanged as inert historical state. Any apply/verify failure before seal restores the exact legacy unit/application and service state. Retirement does not touch CT200, complaints, forum state, or v2 data.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:74:The final retirement task does not delete `/opt/skladchik-moderator-assistant`. The existing app-cloud backup scheduler still schedules `skladchik-moderator-assistant`, and its worker captures `/var/lib/skladchik-moderator-assistant/state.sqlite3` plus `/opt/skladchik-moderator-assistant`. Deleting the legacy app directory would therefore break the next scheduled app backup. Retirement is corrected to disable/stop the old service and remove only its systemd unit/endpoint while preserving the exact legacy app and StateDirectory as inert, byte-pinned historical payload. The task read-only proves the existing queue/audit/worker backup contract before and after retirement; backup runtime itself is not modified.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:76:The old MVP unit uses `DynamicUser=yes` with `StateDirectory=skladchik-moderator-assistant`. Retirement accepts the normal directory layout or the exact systemd-managed `/var/lib/skladchik-moderator-assistant` symlink resolving to `/var/lib/private/skladchik-moderator-assistant`; the SQLite file itself must remain a regular non-symlink file.","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:6:4e119cef286d48ac4675235a82309e0c1087316bcada25bc6f8f43aea665e1dd tasks/skladchik-moderator-v2-application-v1/assets/app-payload.tar.gz","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:7:cf37824d4bb8d0d412d505cfeca33c81ddc37ac31ceedb6b131181653895fad1 tasks/skladchik-moderator-v2-application-v1/assets/app/config.json","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:8:761de78bd15049d408ed2f109a0fcd87e453d702defdf0e8d1547e1b35a55974 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/__init__.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:9:3e90e6c148a2b7ba52072be35280130f00fb966cfb94b76908fbd2eecd965b35 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/ads.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:10:5664ff8e9d45381a0c08a71a794060e60db8f523bd32911b390d28014066fc6c tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/analyzer.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:11:56f52f89fff1468d5e13da29c3c10cf60bc0aea06d71be871dcfc805aec23b60 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/cli.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:12:122e44d95edfc1c205cdee589ab83a9ccbce724a7951b569995e29171d4cb393 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/collector.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:13:0fd4e356a70e56f7293492b5f3d7677cc1a31156ba1964b3997c8852483edf63 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/competitors.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:14:bb207fe35de98aae0013a15eb27294e24902beeda01daf4f9b404bd8600165bc tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/config.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:15:ba63cc5d4f4e68a0cdd82c985d4fd5989fe9cf4c3beefb94ef1643d4a83bb80e tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/db.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:16:9e3bfd6a9481768800897f4a6be27e68f27e10bec96d3dda567407443b03bc99 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/forum.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:17:5b61133d9b2a72a8e5b86c01627899f60c988dee52fc7fdcc7adb7f82ebe1d47 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/normalize.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:18:88b5d4874b865ebe82ece25448a55bd083f4fb95a2c203621d715b6f0f58df57 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/rules.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:19:4c400f907b0c8fd57a4959a2d3fbc83206fd577e4429b7947e372f15c1637c25 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/schema.sql","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:20:6710a6dae5c3889412c823af20a989d2f1f072dd03451c9b1e00b6078aab570d tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/webapp.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:21:3d7e4c0054a958c6f440ffc2ee112360e1d7a433d3371590deb7575f89323f3b tasks/skladchik-moderator-v2-application-v1/assets/app/wsgi.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:22:f2f353dd56327395e03d26942deadf4987ac9b3a8a244dc87b3bddbbf9a301d9 tasks/skladchik-moderator-v2-application-v1/assets/pve03-app.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:23:04a441d36e41d30e1190dab7e71d3c05fb5733248ee7308f9b1b675abbf414b9 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.service","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:24:fee9af8ac8ab3f875a2860178b1029a1bc2fa251bf6e42a021585e02eee90c17 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.timer","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:25:d9e99cb8f07c328842f1eebc6d262dca623173cb9cfdd7e2afb4b279449a9519 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.service","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:26:37cd7bfe11a6c1cd70d5da7c62af19d7147e5f70a9641a0641cac8acbc709bb2 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.timer","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:27:9789f77fc9d6e246cacbc915b178ed2fedcf1367f7af8fe20a98881abe6597c5 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.service","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:28:a56c7d0c1bef8917f2407cabc9e27d0461b19f5af2698e556365d00673a93180 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.timer","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:29:e9cb92c0702ae26a0c6a063ffaaab0f1bafc08a82c05263509e112ff7847edae tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-web.service","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:30:6e7e7f45c756bec56a64321ebb6ca89d8f4edb8e070a57481e730e2c876deeeb tasks/skladchik-moderator-v2-application-v1/phases/apply.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:31:d17e4d6f9e9eece7672bccd18dec0fb533810fafb469e0e2ca99753fa5fe4136 tasks/skladchik-moderator-v2-application-v1/phases/dry-run.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:32:8a39aef9926a6cf55c659937817bc5dc12657d5ef1f7edd549dc99530b88ade9 tasks/skladchik-moderator-v2-application-v1/phases/preflight.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:33:5157ec8da4bcfc0b88ccac54bed52a3ffeb676d5513cdb3f6b4ed5955658f76a tasks/skladchik-moderator-v2-application-v1/phases/prepare.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:34:403263caebb4925ada3957e0dbc852cf1813ba4ceda3fb308c33b2b22107c955 tasks/skladchik-moderator-v2-application-v1/phases/rollback.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:35:11f128d5da0a7c1276b77e10400e825a267633828cd173c0d8e5582902d28443 tasks/skladchik-moderator-v2-application-v1/phases/seal.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:36:3fba9b905dccf09dff024684894443d3b670b973f67c9db7653efde0b1c42fe8 tasks/skladchik-moderator-v2-application-v1/phases/verify.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:37:b9b2aa5fa48836fecbec286136377b8d6af00383df9e1a97b5ba0833c4099d27 tasks/skladchik-moderator-v2-application-v1/task.json","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:38:4b4c8d38c0e6613ec6cf2c6aaf873c506fffe5fd400566255e2a77618da7bb90 tasks/skladchik-moderator-v2-application-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:39:0c23274ab9b0ea843595689536284c86bdc7746220ebb4f140ccd1fff2c752bd tasks/skladchik-moderator-v2-application-v1/tools/test_contract.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:40:6f9b3c541c451c4b9c0d2d394931c1b7e868349bef3e53167160298df703f2f6 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/auth-selftest.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:41:25eaabbddc54235aaafd2f5829c7e8ed9d1defcf76b8327cf347aeefda823ae0 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/forum.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:42:c2cccab25c73ec554d1a51f9dccf32343b50f5ff3efc4d65c55361032f1a2c30 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/pve03-auth-classifier.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:43:5f6e75e0b38671c55129e2975c64ab8522197f997dae370e3f513628452f1783 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/apply.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:44:caec61da54d9c40bd7cfed623617002c06a18e9604195b6057eb9e4e9bbee294 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/dry-run.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:45:92ee9f19e3a83c1c244c033a277ed5ad312bd7396fd2b3fb9bdd4047aa847957 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/preflight.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:46:7c1ba5eb1e973ac5a2dd1651c89a05ba5a133f5bcf59ec216395887f9019ed7b tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/prepare.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:47:1c95a608369828b9da7c5d78fe630b5b4d947a799cbd22006a02be85686d5d75 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/rollback.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:48:2ab9124cc1428a68ca55c86fe6184f9fce8885dc353218a2caa2d8af742f0c89 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/seal.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:49:06e4185e2678a7e8a71514dd41b1845e84b1099f98003e234929aaa23d1c5d4a tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/verify.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:50:40ed940ba18618988294feede2a24d825a95c8a9ba84d5491f46664466be6b2e tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/task.json","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:51:3d0827c41d83923e0672d2d07f0502f42abc55b825f2f5e5c42dafa851c69419 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:52:49c5c42d757ee1e37123a5dc945d2a17631b74c394dbcd621e90ed7ad132cc72 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/test_contract.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:53:011936d623941792240f8687443220e81357b68b17d419ebcdaa721d0473c63b tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/edge-cookie-source.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:54:56a9ab7d9169987c3b8fae6de29e6a3adb4538e34664d1b77c8c6203a9003474 tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/pve03-cookie.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:55:fb70f92b602588b73eb7eec5816387669576b5de2e07b69ff90de328bef3026b tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/apply.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:56:1ed1ad4b17f96dee387b23989b3e3a974ed501cd5d694cade4d085d52dd295a1 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/dry-run.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:57:a839dd24e8b7c786b3130bd716841e0ced43c49ea1ab3314aebbeaca07dfd436 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/preflight.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:58:e377d14af824721cc1986889f1291da70b87901d1837769390d378f4d2fe5e13 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/prepare.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:59:014cf33ef917d193385449fc13201cefa84148608eb4fd6d3e5f30be06d1dd73 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/rollback.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:60:268b03a7b39225bfb2c97c4c87827c819e2ed727138b6158ff976469daf6887a tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/seal.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:61:6dafb047863c6df90898beeb99dd5ef04862afae3b8a3af57eb8290c671434a6 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/verify.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:62:feec58b4018f777a212520a795e7605455c6fb41da7a1792b60e1d57981c4689 tasks/skladchik-moderator-v2-cookie-onboarding-v1/task.json","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:63:4a8ae4ac4d749a4a7d10b8a21d2729dc2242ef4b0cd3b06f28ac89dd2bbff92c tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:64:93cb00411e45d9bdd9cb035869fe2be230f6147e76a8898a36606c51d9bcb568 tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/test_contract.py","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:65:2ee3682cb57e7b6d04195a37b8f7acafde5cb2dc9ca28820e25c7143b3db4706 tasks/skladchik-moderator-v2-edge-egress-v1/assets/edge-egress.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:66:207793e2fa360abb88d535912d7d013af8bc822f4ffb1d8f55a3ea0967dc1ad6 tasks/skladchik-moderator-v2-edge-egress-v1/assets/pve03-egress.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:67:3c32c482e3232df8a2c4d25f553e8e7198c33a378e0600f53c01f71d14d9b3f6 tasks/skladchik-moderator-v2-edge-egress-v1/phases/apply.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:68:c51e41420b857f7d0ff2b8a16c8d0a339b4b942020d4ae59f80721e113e37eec tasks/skladchik-moderator-v2-edge-egress-v1/phases/dry-run.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:69:d5e83720f2d842f4a1a2aba7ae4a55ce5494d16a43aa67f280d21c3cbed74d16 tasks/skladchik-moderator-v2-edge-egress-v1/phases/preflight.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:70:ee7ba739521639244e37ecf63d218bc18202701e53970f46eb987f7f3c6cb3b5 tasks/skladchik-moderator-v2-edge-egress-v1/phases/prepare.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:71:23aa44a61d9a6197ef236cc71b3f5eb4f9c38cdb24ae68eaa52113d34ac96ac0 tasks/skladchik-moderator-v2-edge-egress-v1/phases/rollback.sh","refs/heads/cr-2026-0058-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:72:ef7485307bd7e9b49c9102268db8b729049226f631441362ad3c2c5227516c12 tasks/skladchik-moderator-v2-edge-egress-v1/phases/seal.sh"],"rc":0,"stderr_sha256":null,"stdout_sha256":"b13094744d9f29c47fc973085e76f2db0645d2b5259d8f98bac8280c34c906c8"}},"refs/heads/cr-2026-0066-legacy-backup-target-retirement":{"diff_names":{"lines":["D\t.gitea/workflows/validate-kb.yml","M\tACTIVE_CHANGES.md","M\tAGENTS.md","M\tCURRENT_CONTEXT.md","D\tKB_START_HERE.md","M\tREADME.md","D\tchanges/CR-2026-0018/acceptance.json","D\tchanges/CR-2026-0018/caller-inventory-requirements.md","D\tchanges/CR-2026-0018/design.md","A\tchanges/CR-2026-0018/evidence.md","D\tchanges/CR-2026-0018/execution-contract.md","A\tchanges/CR-2026-0018/plan.json","D\tchanges/CR-2026-0018/plan.md","D\tchanges/CR-2026-0018/regression-cases-draft.json","D\tchanges/CR-2026-0018/request.json","D\tchanges/CR-2026-0018/review-decision.md","M\tchanges/CR-2026-0018/risk.md","M\tchanges/CR-2026-0018/rollback.md","A\tchanges/CR-2026-0018/task-package.sha256","D\tchanges/CR-2026-0018/task-reference.md","M\tchanges/CR-2026-0018/tests.md","D\tchanges/CR-2026-0018/threat-model.md","A\tchanges/CR-2026-0019/evidence.md","A\tchanges/CR-2026-0019/plan.json","A\tchanges/CR-2026-0019/risk.md","A\tchanges/CR-2026-0019/rollback.md","A\tchanges/CR-2026-0019/source-freeze.sha256","A\tchanges/CR-2026-0019/task-package.sha256","A\tchanges/CR-2026-0019/tests.md","A\tchanges/CR-2026-0026/design-package.sha256","A\tchanges/CR-2026-0026/discovery.md","A\tchanges/CR-2026-0026/implementation.md","A\tchanges/CR-2026-0026/plan.json","A\tchanges/CR-2026-0026/risk.md","A\tchanges/CR-2026-0026/rollback.md","A\tchanges/CR-2026-0026/source-provenance.tsv","A\tchanges/CR-2026-0026/task-package.sha256","A\tchanges/CR-2026-0026/tests.md","A\tchanges/CR-2026-0027/design-package.sha256","A\tchanges/CR-2026-0027/discovery.md","A\tchanges/CR-2026-0027/implementation.md","A\tchanges/CR-2026-0027/plan.json","A\tchanges/CR-2026-0027/risk.md","A\tchanges/CR-2026-0027/rollback.md","A\tchanges/CR-2026-0027/source-provenance.tsv","A\tchanges/CR-2026-0027/task-package.sha256","A\tchanges/CR-2026-0027/tests.md","A\tchanges/CR-2026-0028/design-package.sha256","A\tchanges/CR-2026-0028/discovery.md","A\tchanges/CR-2026-0028/implementation.md","A\tchanges/CR-2026-0028/plan.json","A\tchanges/CR-2026-0028/risk.md","A\tchanges/CR-2026-0028/rollback.md","A\tchanges/CR-2026-0028/source-provenance.tsv","A\tchanges/CR-2026-0028/task-package.sha256","A\tchanges/CR-2026-0028/tests.md","A\tchanges/CR-2026-0029/design-package.sha256","A\tchanges/CR-2026-0029/discovery.md","A\tchanges/CR-2026-0029/implementation.md","A\tchanges/CR-2026-0029/plan.json","A\tchanges/CR-2026-0029/risk.md","A\tchanges/CR-2026-0029/rollback.md","A\tchanges/CR-2026-0029/source-provenance.tsv","A\tchanges/CR-2026-0029/task-package.sha256","A\tchanges/CR-2026-0029/tests.md","A\tchanges/CR-2026-0030/design-package.sha256","A\tchanges/CR-2026-0030/discovery.md","A\tchanges/CR-2026-0030/implementation.md","A\tchanges/CR-2026-0030/plan.json","A\tchanges/CR-2026-0030/risk.md","A\tchanges/CR-2026-0030/rollback.md","A\tchanges/CR-2026-0030/source-provenance.tsv","A\tchanges/CR-2026-0030/task-package.sha256","A\tchanges/CR-2026-0030/tests.md","A\tchanges/CR-2026-0031/design-package.sha256","A\tchanges/CR-2026-0031/discovery.md","A\tchanges/CR-2026-0031/implementation.md","A\tchanges/CR-2026-0031/risk.md","A\tchanges/CR-2026-0031/source-provenance.tsv","A\tchanges/CR-2026-0031/task-package.sha256","A\tchanges/CR-2026-0031/tests.md","A\tchanges/CR-2026-0032/README.md","A\tchanges/CR-2026-0032/design-package.sha256","A\tchanges/CR-2026-0032/task-package.sha256","A\tchanges/CR-2026-0033/README.md","A\tchanges/CR-2026-0033/design-package.sha256","A\tchanges/CR-2026-0033/task-package.sha256","A\tchanges/CR-2026-0034/README.md","A\tchanges/CR-2026-0034/design-package.sha256","A\tchanges/CR-2026-0034/task-package.sha256","A\tchanges/CR-2026-0035/discovery.md","A\tchanges/CR-2026-0035/implementation.md","A\tchanges/CR-2026-0035/package.sha256","A\tchanges/CR-2026-0035/risk.md","A\tchanges/CR-2026-0035/source-provenance.tsv","A\tchanges/CR-2026-0035/tests.md","A\tchanges/CR-2026-0036/discovery.md","A\tchanges/CR-2026-0036/implementation.md","A\tchanges/CR-2026-0036/package.sha256","A\tchanges/CR-2026-0036/risk.md","A\tchanges/CR-2026-0036/source-provenance.tsv","A\tchanges/CR-2026-0036/tests.md","A\tchanges/CR-2026-0046/discovery.md","A\tchanges/CR-2026-0046/implementation.md","A\tchanges/CR-2026-0046/risk.md","A\tchanges/CR-2026-0046/source-provenance.tsv","A\tchanges/CR-2026-0046/task-package.sha256","A\tchanges/CR-2026-0046/tests.md","A\tchanges/CR-2026-0047/task-package.sha256","A\tchanges/CR-2026-0048/discovery.md","A\tchanges/CR-2026-0048/implementation.md","A\tchanges/CR-2026-0048/risk.md","A\tchanges/CR-2026-0048/source-provenance.tsv","A\tchanges/CR-2026-0048/task-package.sha256","A\tchanges/CR-2026-0048/tests.md","A\tchanges/CR-2026-0049/discovery.md","A\tchanges/CR-2026-0049/implementation.md","A\tchanges/CR-2026-0049/risk.md","A\tchanges/CR-2026-0049/source-provenance.tsv","A\tchanges/CR-2026-0049/task-package.sha256"],"rc":0,"stderr_sha256":null,"stdout_sha256":"9fa5851c1315be92bf7836d39b07a8ea66bf7530d2842d02f9e0f99a5e23a9e7"},"exists":true,"vm200":{"lines":["refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:12:- Recovery after the initial external-network timeout uses a dedicated `skladchik-moderator-v2-edge-egress-v1` task: CT200 alone uses edge-vm `[PRIVATE_IP]` as its default gateway; edge-vm NATs only `[PRIVATE_IP]/32` into its already-existing NetBird `wt0` default exit (table 7120). No NetBird management policy is changed.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:26:Authenticated section evidence on 2026-08-12 showed 107 `discussionListItem` nodes, 106 `PreviewTooltip` markers and 517 root-relative `threads/...` hrefs. `skladchik-moderator-v2-xf1-parser-hotfix-v1` overlays only `forum.py` and `ads.py`, preserving XF2 support while adding XF1 listing/topic/message/search parsing and root-relative URL resolution. Cookie onboarding is fail-closed on the parser hotfix seal and exact installed module SHA values.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:42:The first controlled cookie apply proved the edge-vm source jar before mutation, installed it, then failed only at the v2 `auth-check`; the apply error path removed the CT200 cookie, disabled collector/competitor timers, and removed transient pve03 staging. The divergence was between two authentication classifiers: edge-vm proves the moderator session by authenticated XenForo 1 `discussionListItem` rows, while v2 still downgraded the same cookie-backed section using a text-only login heuristic. `skladchik-moderator-v2-auth-classification-hotfix-v1` preserves the sealed XF1 parser and changes only section authentication classification: a cookie-backed section that parses canonical topic rows is positive auth evidence. This is bounded by the already-observed public response yielding zero rows ","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:54:The authenticated bootstrap reached 104 listed topics and 40 detailed topics but produced zero analyses because every analyzed detail failed at `stage_history.stage = %s` with PostgreSQL `text = bytea`. The application connection inherited `SQL_ASCII`, so Psycopg returned text values as Python bytes and adapted the fetched stage back as `bytea` on the next parameterized query. The fix is at the connection boundary, not an SQL cast: `skladchik-moderator-v2-db-text-encoding-hotfix-v1` pins Psycopg `client_encoding=UTF8`, proves the baseline bytes failure against existing data, then performs a pre-mutation UTF8 probe across every existing app-facing text column and the exact formerly failing stage-history query; apply/verify repeat that proof through the installed module. No schema or data rewr","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:58:The post-cookie health failure after successful authenticated collection (104 listed topics, 17 analyses in the triggering run; 65 analyses persisted overall) was isolated to rule state. The formatting-rule fetch inherited the moderator cookie and was redirected to XenForo `/login/two-step`, creating a non-approved rule-source revision. Rule pages are public policy sources, so `skladchik-moderator-v2-rules-public-sync-hotfix-v1` fetches them through an independent cookie-free Requests session and requires the redirected final URL to preserve the expected rule thread id. Before mutation, the live dry-run requires each current public content hash to already exist as an explicitly approved historical source; a genuinely new rule revision therefore still stops for manual review and is never auto","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:62:The final cookie bootstrap exposed a collector-only SQL defect after all 104 section topics had already been detailed: `global_search_hits` used `ON CONFLICT DO UPDATE` without the unique-key inference target, so PostgreSQL rejected every whole-site duplicate-search upsert for the remaining four topics. Because detail state is committed before duplicate search and analysis, those topics then became ineligible for another detail fetch for two days. `skladchik-moderator-v2-collector-resume-hotfix-v1` fixes the upsert against the existing `UNIQUE(source_topic_id,query_kind,query_text,hit_url)` key and adds a cached-detail analysis backlog that retries topics whose latest committed detail has no analysis at or after that detail timestamp. Its dry-run executes the corrected upsert twice inside a ","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:70:After cookie onboarding is SEALED and current v2 health/timers are re-proven, `skladchik-moderator-v2-old-mvp-retirement-v1` retires only the legacy pve01 operational service. The task pins the exact legacy unit/app/rules bytes and version, captures root-only rollback copies, disables/stops the service, removes `/etc/systemd/system/skladchik-moderator-assistant.service` and `/opt/skladchik-moderator-assistant`, and preserves `/var/lib/skladchik-moderator-assistant` unchanged as inert historical state. Any apply/verify failure before seal restores the exact legacy unit/application and service state. Retirement does not touch CT200, complaints, forum state, or v2 data.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:74:The final retirement task does not delete `/opt/skladchik-moderator-assistant`. The existing app-cloud backup scheduler still schedules `skladchik-moderator-assistant`, and its worker captures `/var/lib/skladchik-moderator-assistant/state.sqlite3` plus `/opt/skladchik-moderator-assistant`. Deleting the legacy app directory would therefore break the next scheduled app backup. Retirement is corrected to disable/stop the old service and remove only its systemd unit/endpoint while preserving the exact legacy app and StateDirectory as inert, byte-pinned historical payload. The task read-only proves the existing queue/audit/worker backup contract before and after retirement; backup runtime itself is not modified.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/implementation.md:76:The old MVP unit uses `DynamicUser=yes` with `StateDirectory=skladchik-moderator-assistant`. Retirement accepts the normal directory layout or the exact systemd-managed `/var/lib/skladchik-moderator-assistant` symlink resolving to `/var/lib/private/skladchik-moderator-assistant`; the SQLite file itself must remain a regular non-symlink file.","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:6:4e119cef286d48ac4675235a82309e0c1087316bcada25bc6f8f43aea665e1dd tasks/skladchik-moderator-v2-application-v1/assets/app-payload.tar.gz","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:7:cf37824d4bb8d0d412d505cfeca33c81ddc37ac31ceedb6b131181653895fad1 tasks/skladchik-moderator-v2-application-v1/assets/app/config.json","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:8:761de78bd15049d408ed2f109a0fcd87e453d702defdf0e8d1547e1b35a55974 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/__init__.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:9:3e90e6c148a2b7ba52072be35280130f00fb966cfb94b76908fbd2eecd965b35 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/ads.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:10:5664ff8e9d45381a0c08a71a794060e60db8f523bd32911b390d28014066fc6c tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/analyzer.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:11:56f52f89fff1468d5e13da29c3c10cf60bc0aea06d71be871dcfc805aec23b60 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/cli.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:12:122e44d95edfc1c205cdee589ab83a9ccbce724a7951b569995e29171d4cb393 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/collector.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:13:0fd4e356a70e56f7293492b5f3d7677cc1a31156ba1964b3997c8852483edf63 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/competitors.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:14:bb207fe35de98aae0013a15eb27294e24902beeda01daf4f9b404bd8600165bc tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/config.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:15:ba63cc5d4f4e68a0cdd82c985d4fd5989fe9cf4c3beefb94ef1643d4a83bb80e tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/db.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:16:9e3bfd6a9481768800897f4a6be27e68f27e10bec96d3dda567407443b03bc99 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/forum.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:17:5b61133d9b2a72a8e5b86c01627899f60c988dee52fc7fdcc7adb7f82ebe1d47 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/normalize.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:18:88b5d4874b865ebe82ece25448a55bd083f4fb95a2c203621d715b6f0f58df57 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/rules.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:19:4c400f907b0c8fd57a4959a2d3fbc83206fd577e4429b7947e372f15c1637c25 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/schema.sql","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:20:6710a6dae5c3889412c823af20a989d2f1f072dd03451c9b1e00b6078aab570d tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/webapp.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:21:3d7e4c0054a958c6f440ffc2ee112360e1d7a433d3371590deb7575f89323f3b tasks/skladchik-moderator-v2-application-v1/assets/app/wsgi.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:22:f2f353dd56327395e03d26942deadf4987ac9b3a8a244dc87b3bddbbf9a301d9 tasks/skladchik-moderator-v2-application-v1/assets/pve03-app.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:23:04a441d36e41d30e1190dab7e71d3c05fb5733248ee7308f9b1b675abbf414b9 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.service","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:24:fee9af8ac8ab3f875a2860178b1029a1bc2fa251bf6e42a021585e02eee90c17 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.timer","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:25:d9e99cb8f07c328842f1eebc6d262dca623173cb9cfdd7e2afb4b279449a9519 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.service","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:26:37cd7bfe11a6c1cd70d5da7c62af19d7147e5f70a9641a0641cac8acbc709bb2 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.timer","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:27:9789f77fc9d6e246cacbc915b178ed2fedcf1367f7af8fe20a98881abe6597c5 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.service","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:28:a56c7d0c1bef8917f2407cabc9e27d0461b19f5af2698e556365d00673a93180 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.timer","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:29:e9cb92c0702ae26a0c6a063ffaaab0f1bafc08a82c05263509e112ff7847edae tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-web.service","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:30:6e7e7f45c756bec56a64321ebb6ca89d8f4edb8e070a57481e730e2c876deeeb tasks/skladchik-moderator-v2-application-v1/phases/apply.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:31:d17e4d6f9e9eece7672bccd18dec0fb533810fafb469e0e2ca99753fa5fe4136 tasks/skladchik-moderator-v2-application-v1/phases/dry-run.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:32:8a39aef9926a6cf55c659937817bc5dc12657d5ef1f7edd549dc99530b88ade9 tasks/skladchik-moderator-v2-application-v1/phases/preflight.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:33:5157ec8da4bcfc0b88ccac54bed52a3ffeb676d5513cdb3f6b4ed5955658f76a tasks/skladchik-moderator-v2-application-v1/phases/prepare.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:34:403263caebb4925ada3957e0dbc852cf1813ba4ceda3fb308c33b2b22107c955 tasks/skladchik-moderator-v2-application-v1/phases/rollback.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:35:11f128d5da0a7c1276b77e10400e825a267633828cd173c0d8e5582902d28443 tasks/skladchik-moderator-v2-application-v1/phases/seal.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:36:3fba9b905dccf09dff024684894443d3b670b973f67c9db7653efde0b1c42fe8 tasks/skladchik-moderator-v2-application-v1/phases/verify.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:37:b9b2aa5fa48836fecbec286136377b8d6af00383df9e1a97b5ba0833c4099d27 tasks/skladchik-moderator-v2-application-v1/task.json","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:38:4b4c8d38c0e6613ec6cf2c6aaf873c506fffe5fd400566255e2a77618da7bb90 tasks/skladchik-moderator-v2-application-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:39:0c23274ab9b0ea843595689536284c86bdc7746220ebb4f140ccd1fff2c752bd tasks/skladchik-moderator-v2-application-v1/tools/test_contract.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:40:6f9b3c541c451c4b9c0d2d394931c1b7e868349bef3e53167160298df703f2f6 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/auth-selftest.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:41:25eaabbddc54235aaafd2f5829c7e8ed9d1defcf76b8327cf347aeefda823ae0 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/forum.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:42:c2cccab25c73ec554d1a51f9dccf32343b50f5ff3efc4d65c55361032f1a2c30 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/pve03-auth-classifier.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:43:5f6e75e0b38671c55129e2975c64ab8522197f997dae370e3f513628452f1783 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/apply.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:44:caec61da54d9c40bd7cfed623617002c06a18e9604195b6057eb9e4e9bbee294 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/dry-run.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:45:92ee9f19e3a83c1c244c033a277ed5ad312bd7396fd2b3fb9bdd4047aa847957 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/preflight.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:46:7c1ba5eb1e973ac5a2dd1651c89a05ba5a133f5bcf59ec216395887f9019ed7b tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/prepare.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:47:1c95a608369828b9da7c5d78fe630b5b4d947a799cbd22006a02be85686d5d75 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/rollback.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:48:2ab9124cc1428a68ca55c86fe6184f9fce8885dc353218a2caa2d8af742f0c89 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/seal.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:49:06e4185e2678a7e8a71514dd41b1845e84b1099f98003e234929aaa23d1c5d4a tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/verify.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:50:40ed940ba18618988294feede2a24d825a95c8a9ba84d5491f46664466be6b2e tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/task.json","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:51:3d0827c41d83923e0672d2d07f0502f42abc55b825f2f5e5c42dafa851c69419 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:52:49c5c42d757ee1e37123a5dc945d2a17631b74c394dbcd621e90ed7ad132cc72 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/test_contract.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:53:011936d623941792240f8687443220e81357b68b17d419ebcdaa721d0473c63b tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/edge-cookie-source.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:54:56a9ab7d9169987c3b8fae6de29e6a3adb4538e34664d1b77c8c6203a9003474 tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/pve03-cookie.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:55:fb70f92b602588b73eb7eec5816387669576b5de2e07b69ff90de328bef3026b tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/apply.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:56:1ed1ad4b17f96dee387b23989b3e3a974ed501cd5d694cade4d085d52dd295a1 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/dry-run.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:57:a839dd24e8b7c786b3130bd716841e0ced43c49ea1ab3314aebbeaca07dfd436 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/preflight.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:58:e377d14af824721cc1986889f1291da70b87901d1837769390d378f4d2fe5e13 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/prepare.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:59:014cf33ef917d193385449fc13201cefa84148608eb4fd6d3e5f30be06d1dd73 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/rollback.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:60:268b03a7b39225bfb2c97c4c87827c819e2ed727138b6158ff976469daf6887a tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/seal.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:61:6dafb047863c6df90898beeb99dd5ef04862afae3b8a3af57eb8290c671434a6 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/verify.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:62:feec58b4018f777a212520a795e7605455c6fb41da7a1792b60e1d57981c4689 tasks/skladchik-moderator-v2-cookie-onboarding-v1/task.json","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:63:4a8ae4ac4d749a4a7d10b8a21d2729dc2242ef4b0cd3b06f28ac89dd2bbff92c tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:64:93cb00411e45d9bdd9cb035869fe2be230f6147e76a8898a36606c51d9bcb568 tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/test_contract.py","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:65:2ee3682cb57e7b6d04195a37b8f7acafde5cb2dc9ca28820e25c7143b3db4706 tasks/skladchik-moderator-v2-edge-egress-v1/assets/edge-egress.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:66:207793e2fa360abb88d535912d7d013af8bc822f4ffb1d8f55a3ea0967dc1ad6 tasks/skladchik-moderator-v2-edge-egress-v1/assets/pve03-egress.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:67:3c32c482e3232df8a2c4d25f553e8e7198c33a378e0600f53c01f71d14d9b3f6 tasks/skladchik-moderator-v2-edge-egress-v1/phases/apply.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:68:c51e41420b857f7d0ff2b8a16c8d0a339b4b942020d4ae59f80721e113e37eec tasks/skladchik-moderator-v2-edge-egress-v1/phases/dry-run.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:69:d5e83720f2d842f4a1a2aba7ae4a55ce5494d16a43aa67f280d21c3cbed74d16 tasks/skladchik-moderator-v2-edge-egress-v1/phases/preflight.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:70:ee7ba739521639244e37ecf63d218bc18202701e53970f46eb987f7f3c6cb3b5 tasks/skladchik-moderator-v2-edge-egress-v1/phases/prepare.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:71:23aa44a61d9a6197ef236cc71b3f5eb4f9c38cdb24ae68eaa52113d34ac96ac0 tasks/skladchik-moderator-v2-edge-egress-v1/phases/rollback.sh","refs/heads/cr-2026-0066-legacy-backup-target-retirement:changes/CR-2026-0036/package.sha256:72:ef7485307bd7e9b49c9102268db8b729049226f631441362ad3c2c5227516c12 tasks/skladchik-moderator-v2-edge-egress-v1/phases/seal.sh"],"rc":0,"stderr_sha256":null,"stdout_sha256":"9989ff793d051a8863587f029c5c474bae7c794adc87d6e9e566a31f62e43b6c"}},"refs/heads/cr-2026-0070-backup-target-lifecycle-registry":{"diff_names":{"lines":["D\t.gitea/workflows/validate-kb.yml","M\tACTIVE_CHANGES.md","M\tAGENTS.md","M\tCURRENT_CONTEXT.md","D\tKB_START_HERE.md","M\tREADME.md","D\tchanges/CR-2026-0018/acceptance.json","D\tchanges/CR-2026-0018/caller-inventory-requirements.md","D\tchanges/CR-2026-0018/design.md","A\tchanges/CR-2026-0018/evidence.md","D\tchanges/CR-2026-0018/execution-contract.md","A\tchanges/CR-2026-0018/plan.json","D\tchanges/CR-2026-0018/plan.md","D\tchanges/CR-2026-0018/regression-cases-draft.json","D\tchanges/CR-2026-0018/request.json","D\tchanges/CR-2026-0018/review-decision.md","M\tchanges/CR-2026-0018/risk.md","M\tchanges/CR-2026-0018/rollback.md","A\tchanges/CR-2026-0018/task-package.sha256","D\tchanges/CR-2026-0018/task-reference.md","M\tchanges/CR-2026-0018/tests.md","D\tchanges/CR-2026-0018/threat-model.md","A\tchanges/CR-2026-0019/evidence.md","A\tchanges/CR-2026-0019/plan.json","A\tchanges/CR-2026-0019/risk.md","A\tchanges/CR-2026-0019/rollback.md","A\tchanges/CR-2026-0019/source-freeze.sha256","A\tchanges/CR-2026-0019/task-package.sha256","A\tchanges/CR-2026-0019/tests.md","A\tchanges/CR-2026-0026/design-package.sha256","A\tchanges/CR-2026-0026/discovery.md","A\tchanges/CR-2026-0026/implementation.md","A\tchanges/CR-2026-0026/plan.json","A\tchanges/CR-2026-0026/risk.md","A\tchanges/CR-2026-0026/rollback.md","A\tchanges/CR-2026-0026/source-provenance.tsv","A\tchanges/CR-2026-0026/task-package.sha256","A\tchanges/CR-2026-0026/tests.md","A\tchanges/CR-2026-0027/design-package.sha256","A\tchanges/CR-2026-0027/discovery.md","A\tchanges/CR-2026-0027/implementation.md","A\tchanges/CR-2026-0027/plan.json","A\tchanges/CR-2026-0027/risk.md","A\tchanges/CR-2026-0027/rollback.md","A\tchanges/CR-2026-0027/source-provenance.tsv","A\tchanges/CR-2026-0027/task-package.sha256","A\tchanges/CR-2026-0027/tests.md","A\tchanges/CR-2026-0028/design-package.sha256","A\tchanges/CR-2026-0028/discovery.md","A\tchanges/CR-2026-0028/implementation.md","A\tchanges/CR-2026-0028/plan.json","A\tchanges/CR-2026-0028/risk.md","A\tchanges/CR-2026-0028/rollback.md","A\tchanges/CR-2026-0028/source-provenance.tsv","A\tchanges/CR-2026-0028/task-package.sha256","A\tchanges/CR-2026-0028/tests.md","A\tchanges/CR-2026-0029/design-package.sha256","A\tchanges/CR-2026-0029/discovery.md","A\tchanges/CR-2026-0029/implementation.md","A\tchanges/CR-2026-0029/plan.json","A\tchanges/CR-2026-0029/risk.md","A\tchanges/CR-2026-0029/rollback.md","A\tchanges/CR-2026-0029/source-provenance.tsv","A\tchanges/CR-2026-0029/task-package.sha256","A\tchanges/CR-2026-0029/tests.md","A\tchanges/CR-2026-0030/design-package.sha256","A\tchanges/CR-2026-0030/discovery.md","A\tchanges/CR-2026-0030/implementation.md","A\tchanges/CR-2026-0030/plan.json","A\tchanges/CR-2026-0030/risk.md","A\tchanges/CR-2026-0030/rollback.md","A\tchanges/CR-2026-0030/source-provenance.tsv","A\tchanges/CR-2026-0030/task-package.sha256","A\tchanges/CR-2026-0030/tests.md","A\tchanges/CR-2026-0031/design-package.sha256","A\tchanges/CR-2026-0031/discovery.md","A\tchanges/CR-2026-0031/implementation.md","A\tchanges/CR-2026-0031/risk.md","A\tchanges/CR-2026-0031/source-provenance.tsv","A\tchanges/CR-2026-0031/task-package.sha256","A\tchanges/CR-2026-0031/tests.md","A\tchanges/CR-2026-0032/README.md","A\tchanges/CR-2026-0032/design-package.sha256","A\tchanges/CR-2026-0032/task-package.sha256","A\tchanges/CR-2026-0033/README.md","A\tchanges/CR-2026-0033/design-package.sha256","A\tchanges/CR-2026-0033/task-package.sha256","A\tchanges/CR-2026-0034/README.md","A\tchanges/CR-2026-0034/design-package.sha256","A\tchanges/CR-2026-0034/task-package.sha256","A\tchanges/CR-2026-0035/discovery.md","A\tchanges/CR-2026-0035/implementation.md","A\tchanges/CR-2026-0035/package.sha256","A\tchanges/CR-2026-0035/risk.md","A\tchanges/CR-2026-0035/source-provenance.tsv","A\tchanges/CR-2026-0035/tests.md","A\tchanges/CR-2026-0036/discovery.md","A\tchanges/CR-2026-0036/implementation.md","A\tchanges/CR-2026-0036/package.sha256","A\tchanges/CR-2026-0036/risk.md","A\tchanges/CR-2026-0036/source-provenance.tsv","A\tchanges/CR-2026-0036/tests.md","A\tchanges/CR-2026-0046/discovery.md","A\tchanges/CR-2026-0046/implementation.md","A\tchanges/CR-2026-0046/risk.md","A\tchanges/CR-2026-0046/source-provenance.tsv","A\tchanges/CR-2026-0046/task-package.sha256","A\tchanges/CR-2026-0046/tests.md","A\tchanges/CR-2026-0047/task-package.sha256","A\tchanges/CR-2026-0048/discovery.md","A\tchanges/CR-2026-0048/implementation.md","A\tchanges/CR-2026-0048/risk.md","A\tchanges/CR-2026-0048/source-provenance.tsv","A\tchanges/CR-2026-0048/task-package.sha256","A\tchanges/CR-2026-0048/tests.md","A\tchanges/CR-2026-0049/discovery.md","A\tchanges/CR-2026-0049/implementation.md","A\tchanges/CR-2026-0049/risk.md","A\tchanges/CR-2026-0049/source-provenance.tsv","A\tchanges/CR-2026-0049/task-package.sha256"],"rc":0,"stderr_sha256":null,"stdout_sha256":"4ab8dd56aa0daea12c6e08fea70070d993d1984ca1d9ec99b9a210bc995e0d0a"},"exists":true,"vm200":{"lines":["refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/discovery.md:3:- Existing `skladchik-moderator-assistant` is an unused MVP on pve01: one Python file, one rules JSON, SQLite analyses count 0.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/implementation.md:3:Task: `skladchik-moderator-ct200-infrastructure-v1`.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/implementation.md:5:The controlled apply creates CT200 on pve03 using the pinned Debian 13 template, 4 vCPU, 6144 MiB RAM, 1024 MiB swap, 40 GiB local-lvm rootfs, unprivileged mode and nesting. It proves boot and DNS, performs an initial vm200 cloud-quorum backup with restore-validation using the candidate worker before changing live backup runtime, then enrolls vm200 in the canonical VM queue/probe/worker/audit/retention runtime on pve01/pve02/pve03 as required.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:6:cf81f24981ad71f84840f0dc3f7c17d25716ae10d09432de023f2332e41b299c tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-audit","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:7:d5e70fca273e67ec272ea44f73558e28fb707902a09e96497a5fb7cecf4e3336 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-backup-retention-gc","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:8:bd6257397c6ea910df2ea0dd57252b33bccd0bbd965175840486dfe5e079bf96 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-freshness-probe","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:9:91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-node-worker","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:10:6994b8750bb3ced52497699738199a77ba9ac28c51ad23ad6eb3f3576aebbef2 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/homelab-vm-cloud-quorum-queue","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:11:43ff350cd9d98bb521bebde51389ff3b90d3dc4a742b0084586ffd0a1b74f47e tasks/skladchik-moderator-ct200-infrastructure-v1/assets/pve03-ct200.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:12:019a64e294d164e94cb429c63590e2f7e5e607516bdd4e0dd9cf81d7b729b1e9 tasks/skladchik-moderator-ct200-infrastructure-v1/assets/remote-runtime.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:13:7a230f0f29bcbe29c870472ccb8751b04d9f5e6fdd72af226c83ed3ca417f0e0 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/apply.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:14:4b8798cb5035bb026c1e04a655866b5cfd6772ae76ce747b4b1778ed28964886 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/dry-run.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:15:f12792c78635913ef671cf1d0593aed76599617669e75a90cd3462c611df4c74 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/preflight.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:16:3e12eacd397f5a8c10969d20990353993894aa0c6ed94c696724e9a1d3956055 tasks/skladchik-moderator-ct200-infrastructure-v1/phases/prepare.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:17:1b24b43a7167edd0df215951c1c59885a18fffbfe4318939fd5a3a7eafeb181e tasks/skladchik-moderator-ct200-infrastructure-v1/phases/rollback.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:18:c34680c51e83699b9e93e8e2720cce06d90dc2b94e4adbb92548d82368b448eb tasks/skladchik-moderator-ct200-infrastructure-v1/phases/seal.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:19:2730fb3920c07b79a59ce32b0bb8b5d0f5b6569b3430565be4c2da84188ba73c tasks/skladchik-moderator-ct200-infrastructure-v1/phases/verify.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:20:c9ef2aae496c76e4dc955f2eae91eb472c4abdbd83ca6b9019a02fb17cf14d1c tasks/skladchik-moderator-ct200-infrastructure-v1/task.json","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:21:980b88d51feb9115695985870af4b48af884876de8d23ee6678c633ae00beb95 tasks/skladchik-moderator-ct200-infrastructure-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/package.sha256:22:974c6181e543c74ea2bb1a1a392960b98aba8bb1fb8ff111f15fc8d6bbc6d06e tasks/skladchik-moderator-ct200-infrastructure-v1/tools/test_contract.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/risk.md:11:- first vm200 SEALED backup and restore evidence before live enrollment;","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/risk.md:13:- rollback preserves any already sealed vm200 cloud generation/evidence rather than deleting recovery data;","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/tests.md:14:- Regression: retention candidate requires SSH stdin isolation and live plan must emit vm200 after hotfix.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0035/tests.md:15:- Live hotfix proof requires read-only candidate/post-install retention plans to include remote-owned VMIDs and `KEEP|logical=vm200|...|reason=POLICY_NEWEST_2`.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:12:- Recovery after the initial external-network timeout uses a dedicated `skladchik-moderator-v2-edge-egress-v1` task: CT200 alone uses edge-vm `[PRIVATE_IP]` as its default gateway; edge-vm NATs only `[PRIVATE_IP]/32` into its already-existing NetBird `wt0` default exit (table 7120). No NetBird management policy is changed.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:26:Authenticated section evidence on 2026-08-12 showed 107 `discussionListItem` nodes, 106 `PreviewTooltip` markers and 517 root-relative `threads/...` hrefs. `skladchik-moderator-v2-xf1-parser-hotfix-v1` overlays only `forum.py` and `ads.py`, preserving XF2 support while adding XF1 listing/topic/message/search parsing and root-relative URL resolution. Cookie onboarding is fail-closed on the parser hotfix seal and exact installed module SHA values.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:42:The first controlled cookie apply proved the edge-vm source jar before mutation, installed it, then failed only at the v2 `auth-check`; the apply error path removed the CT200 cookie, disabled collector/competitor timers, and removed transient pve03 staging. The divergence was between two authentication classifiers: edge-vm proves the moderator session by authenticated XenForo 1 `discussionListItem` rows, while v2 still downgraded the same cookie-backed section using a text-only login heuristic. `skladchik-moderator-v2-auth-classification-hotfix-v1` preserves the sealed XF1 parser and changes only section authentication classification: a cookie-backed section that parses canonical topic rows is positive auth evidence. This is bounded by the already-observed public response yielding zero rows","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:54:The authenticated bootstrap reached 104 listed topics and 40 detailed topics but produced zero analyses because every analyzed detail failed at `stage_history.stage = %s` with PostgreSQL `text = bytea`. The application connection inherited `SQL_ASCII`, so Psycopg returned text values as Python bytes and adapted the fetched stage back as `bytea` on the next parameterized query. The fix is at the connection boundary, not an SQL cast: `skladchik-moderator-v2-db-text-encoding-hotfix-v1` pins Psycopg `client_encoding=UTF8`, proves the baseline bytes failure against existing data, then performs a pre-mutation UTF8 probe across every existing app-facing text column and the exact formerly failing stage-history query; apply/verify repeat that proof through the installed module. No schema or data rew","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:58:The post-cookie health failure after successful authenticated collection (104 listed topics, 17 analyses in the triggering run; 65 analyses persisted overall) was isolated to rule state. The formatting-rule fetch inherited the moderator cookie and was redirected to XenForo `/login/two-step`, creating a non-approved rule-source revision. Rule pages are public policy sources, so `skladchik-moderator-v2-rules-public-sync-hotfix-v1` fetches them through an independent cookie-free Requests session and requires the redirected final URL to preserve the expected rule thread id. Before mutation, the live dry-run requires each current public content hash to already exist as an explicitly approved historical source; a genuinely new rule revision therefore still stops for manual review and is never aut","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:62:The final cookie bootstrap exposed a collector-only SQL defect after all 104 section topics had already been detailed: `global_search_hits` used `ON CONFLICT DO UPDATE` without the unique-key inference target, so PostgreSQL rejected every whole-site duplicate-search upsert for the remaining four topics. Because detail state is committed before duplicate search and analysis, those topics then became ineligible for another detail fetch for two days. `skladchik-moderator-v2-collector-resume-hotfix-v1` fixes the upsert against the existing `UNIQUE(source_topic_id,query_kind,query_text,hit_url)` key and adds a cached-detail analysis backlog that retries topics whose latest committed detail has no analysis at or after that detail timestamp. Its dry-run executes the corrected upsert twice inside a","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:70:After cookie onboarding is SEALED and current v2 health/timers are re-proven, `skladchik-moderator-v2-old-mvp-retirement-v1` retires only the legacy pve01 operational service. The task pins the exact legacy unit/app/rules bytes and version, captures root-only rollback copies, disables/stops the service, removes `/etc/systemd/system/skladchik-moderator-assistant.service` and `/opt/skladchik-moderator-assistant`, and preserves `/var/lib/skladchik-moderator-assistant` unchanged as inert historical state. Any apply/verify failure before seal restores the exact legacy unit/application and service state. Retirement does not touch CT200, complaints, forum state, or v2 data.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:74:The final retirement task does not delete `/opt/skladchik-moderator-assistant`. The existing app-cloud backup scheduler still schedules `skladchik-moderator-assistant`, and its worker captures `/var/lib/skladchik-moderator-assistant/state.sqlite3` plus `/opt/skladchik-moderator-assistant`. Deleting the legacy app directory would therefore break the next scheduled app backup. Retirement is corrected to disable/stop the old service and remove only its systemd unit/endpoint while preserving the exact legacy app and StateDirectory as inert, byte-pinned historical payload. The task read-only proves the existing queue/audit/worker backup contract before and after retirement; backup runtime itself is not modified.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/implementation.md:76:The old MVP unit uses `DynamicUser=yes` with `StateDirectory=skladchik-moderator-assistant`. Retirement accepts the normal directory layout or the exact systemd-managed `/var/lib/skladchik-moderator-assistant` symlink resolving to `/var/lib/private/skladchik-moderator-assistant`; the SQLite file itself must remain a regular non-symlink file.","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:6:4e119cef286d48ac4675235a82309e0c1087316bcada25bc6f8f43aea665e1dd tasks/skladchik-moderator-v2-application-v1/assets/app-payload.tar.gz","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:7:cf37824d4bb8d0d412d505cfeca33c81ddc37ac31ceedb6b131181653895fad1 tasks/skladchik-moderator-v2-application-v1/assets/app/config.json","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:8:761de78bd15049d408ed2f109a0fcd87e453d702defdf0e8d1547e1b35a55974 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/__init__.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:9:3e90e6c148a2b7ba52072be35280130f00fb966cfb94b76908fbd2eecd965b35 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/ads.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:10:5664ff8e9d45381a0c08a71a794060e60db8f523bd32911b390d28014066fc6c tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/analyzer.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:11:56f52f89fff1468d5e13da29c3c10cf60bc0aea06d71be871dcfc805aec23b60 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/cli.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:12:122e44d95edfc1c205cdee589ab83a9ccbce724a7951b569995e29171d4cb393 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/collector.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:13:0fd4e356a70e56f7293492b5f3d7677cc1a31156ba1964b3997c8852483edf63 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/competitors.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:14:bb207fe35de98aae0013a15eb27294e24902beeda01daf4f9b404bd8600165bc tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/config.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:15:ba63cc5d4f4e68a0cdd82c985d4fd5989fe9cf4c3beefb94ef1643d4a83bb80e tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/db.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:16:9e3bfd6a9481768800897f4a6be27e68f27e10bec96d3dda567407443b03bc99 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/forum.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:17:5b61133d9b2a72a8e5b86c01627899f60c988dee52fc7fdcc7adb7f82ebe1d47 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/normalize.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:18:88b5d4874b865ebe82ece25448a55bd083f4fb95a2c203621d715b6f0f58df57 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/rules.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:19:4c400f907b0c8fd57a4959a2d3fbc83206fd577e4429b7947e372f15c1637c25 tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/schema.sql","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:20:6710a6dae5c3889412c823af20a989d2f1f072dd03451c9b1e00b6078aab570d tasks/skladchik-moderator-v2-application-v1/assets/app/skladchik_moderator/webapp.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:21:3d7e4c0054a958c6f440ffc2ee112360e1d7a433d3371590deb7575f89323f3b tasks/skladchik-moderator-v2-application-v1/assets/app/wsgi.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:22:f2f353dd56327395e03d26942deadf4987ac9b3a8a244dc87b3bddbbf9a301d9 tasks/skladchik-moderator-v2-application-v1/assets/pve03-app.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:23:04a441d36e41d30e1190dab7e71d3c05fb5733248ee7308f9b1b675abbf414b9 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.service","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:24:fee9af8ac8ab3f875a2860178b1029a1bc2fa251bf6e42a021585e02eee90c17 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-collector.timer","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:25:d9e99cb8f07c328842f1eebc6d262dca623173cb9cfdd7e2afb4b279449a9519 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.service","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:26:37cd7bfe11a6c1cd70d5da7c62af19d7147e5f70a9641a0641cac8acbc709bb2 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-competitor.timer","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:27:9789f77fc9d6e246cacbc915b178ed2fedcf1367f7af8fe20a98881abe6597c5 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.service","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:28:a56c7d0c1bef8917f2407cabc9e27d0461b19f5af2698e556365d00673a93180 tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-rules.timer","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:29:e9cb92c0702ae26a0c6a063ffaaab0f1bafc08a82c05263509e112ff7847edae tasks/skladchik-moderator-v2-application-v1/assets/systemd/skladchik-moderator-v2-web.service","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:30:6e7e7f45c756bec56a64321ebb6ca89d8f4edb8e070a57481e730e2c876deeeb tasks/skladchik-moderator-v2-application-v1/phases/apply.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:31:d17e4d6f9e9eece7672bccd18dec0fb533810fafb469e0e2ca99753fa5fe4136 tasks/skladchik-moderator-v2-application-v1/phases/dry-run.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:32:8a39aef9926a6cf55c659937817bc5dc12657d5ef1f7edd549dc99530b88ade9 tasks/skladchik-moderator-v2-application-v1/phases/preflight.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:33:5157ec8da4bcfc0b88ccac54bed52a3ffeb676d5513cdb3f6b4ed5955658f76a tasks/skladchik-moderator-v2-application-v1/phases/prepare.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:34:403263caebb4925ada3957e0dbc852cf1813ba4ceda3fb308c33b2b22107c955 tasks/skladchik-moderator-v2-application-v1/phases/rollback.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:35:11f128d5da0a7c1276b77e10400e825a267633828cd173c0d8e5582902d28443 tasks/skladchik-moderator-v2-application-v1/phases/seal.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:36:3fba9b905dccf09dff024684894443d3b670b973f67c9db7653efde0b1c42fe8 tasks/skladchik-moderator-v2-application-v1/phases/verify.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:37:b9b2aa5fa48836fecbec286136377b8d6af00383df9e1a97b5ba0833c4099d27 tasks/skladchik-moderator-v2-application-v1/task.json","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:38:4b4c8d38c0e6613ec6cf2c6aaf873c506fffe5fd400566255e2a77618da7bb90 tasks/skladchik-moderator-v2-application-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:39:0c23274ab9b0ea843595689536284c86bdc7746220ebb4f140ccd1fff2c752bd tasks/skladchik-moderator-v2-application-v1/tools/test_contract.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:40:6f9b3c541c451c4b9c0d2d394931c1b7e868349bef3e53167160298df703f2f6 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/auth-selftest.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:41:25eaabbddc54235aaafd2f5829c7e8ed9d1defcf76b8327cf347aeefda823ae0 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/forum.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:42:c2cccab25c73ec554d1a51f9dccf32343b50f5ff3efc4d65c55361032f1a2c30 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/assets/pve03-auth-classifier.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:43:5f6e75e0b38671c55129e2975c64ab8522197f997dae370e3f513628452f1783 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/apply.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:44:caec61da54d9c40bd7cfed623617002c06a18e9604195b6057eb9e4e9bbee294 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/dry-run.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:45:92ee9f19e3a83c1c244c033a277ed5ad312bd7396fd2b3fb9bdd4047aa847957 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/preflight.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:46:7c1ba5eb1e973ac5a2dd1651c89a05ba5a133f5bcf59ec216395887f9019ed7b tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/prepare.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:47:1c95a608369828b9da7c5d78fe630b5b4d947a799cbd22006a02be85686d5d75 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/rollback.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:48:2ab9124cc1428a68ca55c86fe6184f9fce8885dc353218a2caa2d8af742f0c89 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/seal.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:49:06e4185e2678a7e8a71514dd41b1845e84b1099f98003e234929aaa23d1c5d4a tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/phases/verify.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:50:40ed940ba18618988294feede2a24d825a95c8a9ba84d5491f46664466be6b2e tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/task.json","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:51:3d0827c41d83923e0672d2d07f0502f42abc55b825f2f5e5c42dafa851c69419 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:52:49c5c42d757ee1e37123a5dc945d2a17631b74c394dbcd621e90ed7ad132cc72 tasks/skladchik-moderator-v2-auth-classification-hotfix-v1/tools/test_contract.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:53:011936d623941792240f8687443220e81357b68b17d419ebcdaa721d0473c63b tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/edge-cookie-source.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:54:56a9ab7d9169987c3b8fae6de29e6a3adb4538e34664d1b77c8c6203a9003474 tasks/skladchik-moderator-v2-cookie-onboarding-v1/assets/pve03-cookie.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:55:fb70f92b602588b73eb7eec5816387669576b5de2e07b69ff90de328bef3026b tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/apply.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:56:1ed1ad4b17f96dee387b23989b3e3a974ed501cd5d694cade4d085d52dd295a1 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/dry-run.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:57:a839dd24e8b7c786b3130bd716841e0ced43c49ea1ab3314aebbeaca07dfd436 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/preflight.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:58:e377d14af824721cc1986889f1291da70b87901d1837769390d378f4d2fe5e13 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/prepare.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:59:014cf33ef917d193385449fc13201cefa84148608eb4fd6d3e5f30be06d1dd73 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/rollback.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:60:268b03a7b39225bfb2c97c4c87827c819e2ed727138b6158ff976469daf6887a tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/seal.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:61:6dafb047863c6df90898beeb99dd5ef04862afae3b8a3af57eb8290c671434a6 tasks/skladchik-moderator-v2-cookie-onboarding-v1/phases/verify.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:62:feec58b4018f777a212520a795e7605455c6fb41da7a1792b60e1d57981c4689 tasks/skladchik-moderator-v2-cookie-onboarding-v1/task.json","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:63:4a8ae4ac4d749a4a7d10b8a21d2729dc2242ef4b0cd3b06f28ac89dd2bbff92c tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/runtime-lib.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:64:93cb00411e45d9bdd9cb035869fe2be230f6147e76a8898a36606c51d9bcb568 tasks/skladchik-moderator-v2-cookie-onboarding-v1/tools/test_contract.py","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:65:2ee3682cb57e7b6d04195a37b8f7acafde5cb2dc9ca28820e25c7143b3db4706 tasks/skladchik-moderator-v2-edge-egress-v1/assets/edge-egress.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:66:207793e2fa360abb88d535912d7d013af8bc822f4ffb1d8f55a3ea0967dc1ad6 tasks/skladchik-moderator-v2-edge-egress-v1/assets/pve03-egress.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:67:3c32c482e3232df8a2c4d25f553e8e7198c33a378e0600f53c01f71d14d9b3f6 tasks/skladchik-moderator-v2-edge-egress-v1/phases/apply.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:68:c51e41420b857f7d0ff2b8a16c8d0a339b4b942020d4ae59f80721e113e37eec tasks/skladchik-moderator-v2-edge-egress-v1/phases/dry-run.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:69:d5e83720f2d842f4a1a2aba7ae4a55ce5494d16a43aa67f280d21c3cbed74d16 tasks/skladchik-moderator-v2-edge-egress-v1/phases/preflight.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:70:ee7ba739521639244e37ecf63d218bc18202701e53970f46eb987f7f3c6cb3b5 tasks/skladchik-moderator-v2-edge-egress-v1/phases/prepare.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:71:23aa44a61d9a6197ef236cc71b3f5eb4f9c38cdb24ae68eaa52113d34ac96ac0 tasks/skladchik-moderator-v2-edge-egress-v1/phases/rollback.sh","refs/heads/cr-2026-0070-backup-target-lifecycle-registry:changes/CR-2026-0036/package.sha256:72:ef7485307bd7e9b49c9102268db8b729049226f631441362ad3c2c5227516c12 tasks/skladchik-moderator-v2-edge-egress-v1/phases/seal.sh"],"rc":0,"stderr_sha256":null,"stdout_sha256":"7fd8c45be9f29ec20392475bb0f6d6e2fe4e944bfd3b954b363ede77248b3bb6"}}},"status":{"lines":[],"rc":0,"stderr_sha256":null,"stdout_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}} -PVE_ACTIVE_INVENTORY={"rc":0,"rows":[{"name":"dns1","node":"pve01","status":"running","type":"lxc","vmid":110},{"name":"dns2","node":"pve02","status":"running","type":"lxc","vmid":111},{"name":"unbound1","node":"pve01","status":"running","type":"lxc","vmid":112},{"name":"unbound2","node":"pve02","status":"running","type":"lxc","vmid":113},{"name":"edge-vm","node":"pve03","status":"running","type":"qemu","vmid":130},{"name":"snikket","node":"pve01","status":"running","type":"qemu","vmid":150},{"name":"forum-prod","node":"pve02","status":"running","type":"qemu","vmid":160},{"name":"core-apps","node":"pve01","status":"running","type":"qemu","vmid":170},{"name":"monitoring","node":"pve01","status":"running","type":"qemu","vmid":171},{"name":"homelab-ops-worker","node":"pve03","status":"running","type":"qemu","vmid":190},{"name":"newfi-prod","node":"pve01","status":"running","type":"qemu","vmid":210},{"name":"newfi-staging","node":"pve03","status":"running","type":"qemu","vmid":211},{"name":"edge-cold-standby","node":"pve02","status":"stopped","type":"qemu","vmid":9130}],"stderr_sha256":null} -STATUS=OK -CHANGES_MADE=false -HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"SUPPORT-260916-INFRA-DR-BACKUPV2-LEGACY-PVE-RETENTION-SOURCE-CAPTURE-489R1","rollback_restored":null,"rollback_started":false,"status":"OK","version":1} +APP484_BEGIN +APP484_DECISION=PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK +APP484_NEXT_GATE=READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1 +APP484_CANARY_DOMAIN=codevipe.ru +APP484_NATIVE_ACTION_PATHS_EXERCISED=2 +APP484_ENTITY_SAVE_CALLS=3 +APP484_ROLLBACK_STARTED=True +APP484_ROLLBACK_RESTORED=True +APP484_PERSISTENT_DRIFT_DETECTED=False +APP484_SAFE_REPORT={"aggregate_restored":true,"anchor_483_commit":"6e5d92e225838298271af5e98956767c04fc065c","anchor_483_decision":"PASS_NATIVE_ACTION_SEMANTICS_INVENTORY_READY","auto_mutation_authorized":false,"backup_dr_mutations":0,"bounce_mid_visible":true,"canary_domain":"codevipe.ru","changes_made":true,"command_id":"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1","commit_operations":0,"database_mutations":2,"decision":"PASS_ONE_FORUM_NATIVE_ACTION_TRANSACTIONAL_CANARY_ROLLED_BACK","dns_mutations":0,"domain":"codevipe.ru","entity_api_canary":true,"entity_save_calls":3,"failure_label":"","initial_receive_admin_email":0,"initial_user_state":"valid","mail_mutations":0,"mail_send_operations":0,"native_action_paths_exercised":2,"native_bounce_processor_invoked":false,"native_bounce_processor_presence_gated":true,"next_gate":"READY_FOR_CANARY_AUDIT_ROLLBACK_GATE_485R1","ok":true,"persistent_drift_detected":false,"persistent_mutation_authorized":false,"postbox_mutations":0,"processor_method_parameter_count":1,"processor_method_present":true,"processor_method_tokens_ok":true,"qga_160_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","qga_160_stdout_sha256":"d0e40b371b64a28a74d8ee38ab3eeb27c5b7942835c1e744414b4dff617cc911","qga_160_transport_rc":0,"raw_sql_write_operations":0,"rollback_restored":true,"rollback_started":true,"selected_fields_restored":true,"subject_class":"VALID_NONBANNED_NONPRIVILEGED_WITH_OPTION_ROW","transactional_rollback_only":true,"unsubscribe_false_mid_visible":true,"unsubscribe_roundtrip_from_zero":true,"xenforo_mutations":2,"xf_version_id":2031170,"xf_version_string":"2.3.11"} +HOMELAB_RESULT_CONTRACT={"changes_made":true,"command_id":"SUPPORT-260916-XENFORO-APP-POLICY-NATIVE-ACTION-TRANSACTIONAL-CANARY-484R1","rollback_restored":true,"rollback_started":true,"status":"OK","version":1} +APP484_END OUTPUT_END CHAT_OUTPUT_END