diff --git a/runtime/history/NEWFI-260907-A-PORTAL200-APPLY4DESIGN5.json b/runtime/history/NEWFI-260907-A-PORTAL200-APPLY4DESIGN5.json new file mode 100644 index 00000000..fe231a2c --- /dev/null +++ b/runtime/history/NEWFI-260907-A-PORTAL200-APPLY4DESIGN5.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "NEWFI-260907-A-PORTAL200-APPLY4DESIGN5", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "read-only", + "component": "newfi-portal200-apply4-local-carrier-recovery5", + "started_at_utc": "2026-09-07T20:27:18Z", + "finished_at_utc": "2026-09-07T20:27:18Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "d8972287e5a04bda3fc17acba988b2651b92ce4193aa3038f19cf27372093f65", + "duplicate_failed_command_blocked": false, + "block_reason": null, + "execution_started": true, + "change_declared": false, + "result_contract_valid": true, + "result_contract_status": null, + "result_contract_error": null, + "command_rc": 0, + "changes_made": false, + "rollback_started": false, + "rollback_restored": null, + "mutation_outcome": "NO_MUTATION", + "sanitized": true, + "secrets_included": false, + "private_addresses_included": false, + "raw_evidence_retained_locally": true, + "raw_evidence_sha256": "58a32ed77e16ff3fbab7bcfac43e592c6e2daf2a7cf6208e7a229a258b6e3a3f", + "sanitized_output_sha256": "58a32ed77e16ff3fbab7bcfac43e592c6e2daf2a7cf6208e7a229a258b6e3a3f", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "LOCAL_APPLY3_CARRIER_RECOVERY5_BEGIN=true\nCOMMAND_ID=NEWFI-260907-A-PORTAL200-APPLY4DESIGN5\nMUTATION_SCOPE=NONE_READ_ONLY\nLOCAL_MUTATIONS_PERFORMED=NO\nTARGET_OLD_COMMAND_ID=NEWFI-260907-PORTAL200-APPLY3\nSEED_COUNT=41\nSEED_BASENAMES=NEWFI.txt,NEWFI-260907-A-PORTAL200-APPLY4PREP1.stdout.txt,NEWFI-260907-B-PORTAL200-RUNNERCONTRACT2_REMOTE.txt,NEWFI-260907-B-PORTAL200-RUNNERCONTRACT2_STDOUT.txt,NEWFI-260907-B-PORTAL200-RUNNERCONTRACT4_REMOTE.txt,NEWFI-260907-B-PORTAL200-RUNNERCONTRACT4_STDOUT.txt,NEWFI-260907-B-PORTAL200-RUNNERCONTRACT5_REMOTE.txt,NEWFI-260907-B-PORTAL200-RUNNERCONTRACT5_STDOUT.txt,newfi-38-portal200-apply.cmd,newfi-39-portal200-rca1.cmd,newfi-40-plink-portal200-rca.cmd,newfi-41-plink-portal200-rca3.cmd,newfi-45-pageant-portal200-rca4.cmd,newfi-46-portal200-http-rca.cmd,newfi-48-portal200-apply2.cmd,newfi-49-portal200-preflight-rca.cmd,newfi-50-portal200-preflight-tail-rca.cmd,newfi-51-portal200-prod-http-network-rca.cmd,newfi-52-prod-public-http-rca.cmd,newfi-53-public-css-regex-rca.cmd,newfi-54-portal200-apply3.cmd,newfi-55-portal200-apply3-rca.cmd,newfi-56-portal200-apply3-failure-contract-rca.cmd,newfi-57-portal200-contract-rule-rca.cmd,newfi-58-portal200-exact-contract-rca.cmd,newfi-59-portal200-contract-ast-rca.cmd,newfi-60-portal200-import-contract-discovery.cmd,newfi-61-portal200-import-compact-discovery.cmd,newfi-62-xf-addon-rebuild-help.cmd,NEWFI45_PORTAL200_RCA4_REMOTE.txt,NEWFI45_PORTAL200_RCA4_REPORT.txt,NEWFI46_PORTAL200_HTTP_RCA_REMOTE.txt,NEWFI46_PORTAL200_HTTP_RCA_REPORT.txt,NEWFI46_PORTAL200_HTTP_RCA_STDOUT.txt,NEWFI48_PORTAL200_APPLY2_REMOTE.txt,NEWFI54_PORTAL200_APPLY3_REMOTE.txt,NEWFI55_REMOTE.txt,NEWFI55_STDOUT.txt,NEWFI56_REMOTE.txt,NEWFI56_STDOUT.txt,NEWFI_PARALLEL_FULL_HANDOFF_2026-09-07.txt\nSEED_SHA256=869d6fdf2d4ac222d9ab4b83242563676f201e6ab21b84360fa73fc7f9bf7195,240d0fad482deb05c93289edd7ac58a84e34b98fc620d1e924b561aace8630bb,92255a714b86966ab5a15a86d18c6257c6c131b20520a6d2d2443b8fe969e93a,9bffe2728a05e52f03ec52fddfcce229588b6f6cff59e8932d6c8b5ae97c592b,e92d1a64266be86cc8e5441ff9f51e2161e35e00ffd12dce1eb049a4b6437dd0,53c8ea2dc91c33b2872da3974ac5a682cbdc907c9d232a29921b674d490d474e,0b4ba8d2b1eef91c627884071bbcdeea8ad9b4f6c04c8650e44eb468253d15f6,a59a4b7a482a0a39a51e08553749c1f15bcf74d4ba449f6d50caf7a6ba60f9b5,8481b33b162a78f0e1398b69fda50f581ace72f87cdfb2a16fb66ceb67fa4987,34245e3a7c02145e7f11e3c7919385ff955e739a5b278ede66f8ec91499a31e4,a398e89eec09cca84a907876dfe46cf491d8b61c402c1dc4e4ec36eb92167845,11ea567ce0485bd87c5da8292c4d01d55e741a85b75fe0bf5073ca33133055f7,96b2de593d982ef7a5cd09c5618e6aabaac259f896a70cc8f1b476b0c3b16a58,2ce247a8dae973819605d246273b294bf23ce1d118c3e8b92517696caff927c9,f0ad32266492990e58a90991f2d6ae808c3e57c1ad53244bfcd26100e163cd73,2d5a55fbb00e63a280680b312d3eff3e28d524e29e8acf9ee8cae77b7c7d1f2e,fae07cfd5e9196871cd8bec8305262c95ecd09654994675e9a4ac4617d761f99,9aca123af4a9674c2bc10f308a65b622dce616cac17fbfe9b58db3782fbd2d0e,c8e9abf642daba2118f3419a00ceaeb0a0cc9a54ae75575e5e903a8db8fd1c1d,92b919e1b4e0b910da5b8357619d853c5791dc73fb8a70d097563128d7c818e7,573c5c94fe59ed072e094281668ce9847dc4a9882019a2b89d8ba5f190d92176,6c98cb81713e91d9866d264e59c513b8a968c4f52bfbad55450957524600bb10,69d7a46640fd020c0daab39c3195ca77ff777242c22b419f66dfcb69be3a8a23,1f99ab8666c4d51844b8e95bf3768cb1b017921824e9ba8857a6579dfaafb6af,e10dcbd211b75626199ed50dda79f34ae169caef24ba747c74b9c79ddaab509e,3621712ba5fecff93abca54c601f4f176d976a67344a506a92d6de79918f05a5,07d2b88b41b30e90058fa1d389cc52d1ea3b20b557a962f9004db720bfc8d2b0,88b9f92828c1ee19537526a1eea93a52c59bc2f32a7034e45508e53cca2e3667,c8827d2f8b0ddc34771c1c71ffbf517d1bd117dcf36b4d3e5439ae262bc86c32,7fc78755edbeee8c49d3d47e26a723c01ee0e1e6b022b8fd2f70ccacdf8f4338,edba9db8c9ddedb0fe3e727c7ed5a255d1da6de82da722431f3db053abff2f38,3ea9e7e83411127caf13af674570f0ef9ac968b13393b0a173ce1344d6a29cf0,1c91f522bb94d4ce292bb451dd847f394362c0a8f4745ae8823a5eed33e2a10b,cfd23052413cad9d435f9aba290956e93d9191312d568cd1cc69437fc602ad03,474b251535372a61e8be1acf215c1cc2240f8414bdd1c5e03309fd5faa2f8f99,71da2a66224075527d8aa04c1281fdb7a2b9f078d76c349fc05b48a4b803a4c3,f4600697557109030fc188376f1407fc02e4ec2eff2c635d81e2438f8a325fe3,65ff188b6b7bd06f59feca719f4fad6e07ff8304ef157425b162b3928f674d31,5f2eb373b3b37d29dff72b8b7d5cc1346283f7b2de02ae2eb95a229e542c5468,b2968ec8823fa4bb7b3d6fd4a25f25d6a486eb9740ecc6ef362d1b31e5f439b2,869d6fdf2d4ac222d9ab4b83242563676f201e6ab21b84360fa73fc7f9bf7195\nDECODED_LAYER_COUNT=64\nSTRONG_LAYER_COUNT=3\nSOURCE_LAYER_COUNT=9\nCHOSEN_LAYER_COUNT=9\nCANDIDATE_LAYER_1_SOURCE=file:NEWFI.txt\nCANDIDATE_LAYER_1_SHA256=869d6fdf2d4ac222d9ab4b83242563676f201e6ab21b84360fa73fc7f9bf7195\nCANDIDATE_LAYER_1_BYTES=57343\nCANDIDATE_LAYER_1_TEXT_BEGIN\n\nПОЛНЫЙ ПАРАЛЛЕЛЬНЫЙ HANDOFF: NEWFI / PORTAL200\nДата сборки: 2026-09-07\nНазначение: начать работу сразу в двух чатах без повторного восстановления контекста.\n\n===============================================================================\n0. КРИТИЧЕСКОЕ РАЗДЕЛЕНИЕ ПРОЕКТОВ\n===============================================================================\n\nПриложенный handoff второго чата относится к KINGOFWOLK CSP.\n\nKINGOFWOLK:\n- agreed safe CSP stage полностью закрыт;\n- shared counter = 0;\n- final accepted checkpoint = KOW-260907-A-FINAL1;\n- его product-state НЕ переносить в NEWFI.\n\nИз KINGOFWOLK для NEWFI переиспользуются только проверенные operational rules:\n- true-parallel read-only direct bridge;\n- один writer для любых изменений;\n- Pageant -> Plink -> pve01 transport;\n- authority checks;\n- homelab-chat-run contracts;\n- immutable Gitea readback;\n- unique COMMAND_ID;\n- fail-closed drift handling;\n- destructive Git / raw SQL mutation prohibition.\n\nПолный KINGOFWOLK handoff приложен ниже как APPENDIX A.\n\n===============================================================================\n1. АКТИВНЫЙ ПРОЕКТ\n===============================================================================\n\nПроект: NEWFI.\nАктивный участок: Portal200.\n\nСейчас НЕ продолжаем KingOfWolk и НЕ занимаемся Linux.\n\nТекущая рабочая проблема:\nпредыдущая change-команда Portal200 APPLY3 не является accepted checkpoint.\nПосле неё выполнены read-only RCA/discovery шаги.\n\n===============================================================================\n2. AUTHORITATIVE GITEA RUNTIME\n===============================================================================\n\nRuntime repo:\nhomelab-admin/homelab-public-context\n\nBranch:\nassistant-runtime\n\nAuthoritative exact readback:\nruntime/history/.txt\n\nНе полагаться на generic latest без точного COMMAND_ID.\n\nКлючевые текущие NEWFI checkpoints:\n\nA) NEWFI-260907-PORTAL200-APPLY3\n\nSTATUS=FAIL\nRC=76\nHOST=pve01\nMODE=change\nCOMPONENT=newfi-portal200-deploy\n\nКритично:\nRESULT_CONTRACT_VALID=false\nRESULT_CONTRACT_STATUS=UNKNOWN\nRESULT_CONTRACT_ERROR=INVALID_CONTRACT:ValueError\nCOMMAND_RC=1\nCHANGES_MADE=unknown\nROLLBACK_STARTED=unknown\nROLLBACK_RESTORED=null\nMUTATION_OUTCOME=UNKNOWN\n\nСледствие:\nAPPLY3 НЕЛЬЗЯ считать ни успешным deploy, ни доказанным rollback.\nНе повторять этот COMMAND_ID.\nНе строить следующий change на предположении, что production/staging точно остались\nв старом состоянии.\n\nB) NEWFI-260907-PORTAL200-CONTRACTAST1\n\nSTATUS=OK\nRC=0\nMODE=read-only\nCOMPONENT=newfi-portal200-contract-ast-rca\nCHANGES_MADE=false\nMUTATION_OUTCOME=NO_MUTATION\n\nНазначение:\nread-only RCA runner result-contract / AST после APPLY3.\n\nЭто accepted diagnostic checkpoint.\n\nC) NEWFI-260907-PORTAL200-IMPORTDISC2\n\nSTATUS=OK\nRC=0\nMODE=read-only\nCOMPONENT=newfi-portal200-import-compact-discovery\nCHANGES_MADE=false\nMUTATION_OUTCOME=NO_MUTATION\n\nНазначение:\ncompact read-only discovery import path + runner-contract requirements.\n\nИз опубликованного evidence видно, что runner contract жёстко валидирует как минимум:\n- поддерживаемую version;\n- command_id exact match;\n- status только OK / BLOCKED / FAIL;\n- changes_made обязан быть boolean.\n\nПри APPLY4 не импровизировать contract JSON:\nсначала перечитать CONTRACTAST1/IMPORTDISC2 и runner source.\n\nD) NEWFI-260907-PORTAL200-REBUILDHELP1\n\nSTATUS=OK\nRC=0\nMODE=read-only\nCOMPONENT=newfi-portal200-rebuild-help\nCHANGES_MADE=false\nMUTATION_OUTCOME=NO_MUTATION\n\nКлючевой вывод:\n\nXenForo CLI поддерживает штатный:\nxf:addon-rebuild [options] [--] \n\nArguments:\nid = Add-On ID\n\nOption:\n-f, --force\nSkip verifying that the add-on is rebuildable\n\nСледствие:\nстарый ручной PHP/import loop не должен быть механизмом следующего deploy.\nСледующий candidate должен опираться на штатный XenForo add-on rebuild,\nНО exact Add-On ID сначала должен быть подтверждён read-only evidence.\nНе hardcode Newfi/Portal только по памяти.\n\n===============================================================================\n3. ГЛАВНЫЙ ВЫВОД ПО APPLY3\n===============================================================================\n\nAPPLY3 имеет ДВЕ независимые проблемы, которые нельзя смешивать:\n\n1. RUNNER / PUBLICATION CONTRACT FAILURE\n Runner отклонил result contract:\n INVALID_CONTRACT:ValueError.\n\n2. PRODUCT MUTATION STATE НЕ ДОКАЗАН\n Outer runtime показывает:\n CHANGES_MADE=unknown\n ROLLBACK_STARTED=unknown\n MUTATION_OUTCOME=UNKNOWN\n\nПоэтому правильная последовательность сейчас:\n\nНЕ:\n\"сразу повторить deploy как APPLY4\"\n\nА:\n- параллельно восстановить current prestate;\n- параллельно построить корректный APPLY4 design;\n- change запускать только после read-only PASS prestate.\n\n===============================================================================\n4. ПАРАЛЛЕЛЬНАЯ МОДЕЛЬ ДЛЯ NEWFI\n===============================================================================\n\nИспользовать проверенную KOW concurrency model.\n\nLANE A = SINGLE WRITER / DEPLOY DESIGN\nLANE B = TRUE PARALLEL READ-ONLY AUDITOR\n\nРазрешено одновременно:\n- Lane A читает Git/Gitea/reference и строит новый carrier;\n- Lane B выполняет direct read-only audit;\n- оба читают immutable Gitea history.\n\nЗапрещено:\n- два change одновременно;\n- два git commit/push writer;\n- два application/XenForo mutation path;\n- повтор failed COMMAND_ID;\n- Lane B mutation.\n\nНа момент фактического APPLY4:\nLane A — единственный writer.\nLane B не должен запускать новый state-sensitive snapshot в середине mutation,\nкроме специально спроектированного concurrent monitor с drift guards.\n\n===============================================================================\n5. COMMAND_ID FAMILY ДЛЯ НОВОЙ ПАРАЛЛЕЛЬНОЙ СЕССИИ\n===============================================================================\n\nЧтобы не путать старую историю:\n\nLane A:\nNEWFI-260907-A-PORTAL200-...\n\nLane B:\nNEWFI-260907-B-PORTAL200-...\n\nКаждый attempt:\nновый COMMAND_ID.\n\nНе reuse:\nNEWFI-260907-PORTAL200-APPLY3\nили любой другой failed ID.\n\n===============================================================================\n6. LANE B — ПЕРВАЯ ЗАДАЧА, КОТОРУЮ МОЖНО ЗАПУСКАТЬ СРАЗУ\n===============================================================================\n\nЦель:\nPOST-APPLY3 CURRENT-STATE RECOVERY AUDIT.\n\nТолько read-only.\n\nLane B должен доказать:\n\n1. Authority:\n /etc/pve/HOMELAB_ASSISTANT_ERROR_REGISTER.md\n /etc/pve/31_HOMELAB_REFERENCE.md\n readable + nonempty + прочитаны.\n\n2. Runner:\n current /usr/local/sbin/homelab-chat-run SHA;\n exact result-contract schema;\n duplicate command semantics.\n\n3. Git:\n authoritative NEWFI repo/worktree;\n branch;\n local HEAD;\n remote HEAD;\n clean/dirty;\n relevant Portal200 files + hashes;\n no unknown local mutation.\n\n4. XenForo environment:\n exact production/staging VM/CT IDs;\n exact docroots;\n exact XenForo versions;\n service health;\n current addon list.\n\n5. Exact Portal Add-On ID:\n resolve from add-on metadata/live XF state.\n Do not mutate.\n Candidate methods:\n - xf:addon-list;\n - addon.json;\n - xf_addon read-only SELECT;\n - existing deployment metadata.\n\n6. Current Portal add-on state:\n installed/active/version;\n pending rebuild/install state if observable read-only;\n relevant cache/code-cache presence;\n current route behavior.\n\n7. APPLY3 aftermath:\n whether product files differ from accepted pre-APPLY3 baseline;\n whether DB/install state changed;\n whether staging changed;\n whether production changed;\n whether rollback evidence exists.\n\n8. Health:\n Nginx / PHP-FPM / MariaDB / related app services;\n HTTP codes for important NEWFI routes.\n\n9. DB:\n SELECT only.\n No UPDATE/INSERT/DELETE/ALTER.\n\n10. Final decision:\n ELIGIBLE_FOR_PORTAL200_APPLY4_PREP\n or exact HOLD_...\n\nLane B output should be bounded and sanitized.\nNo secrets/private credentials.\n\n===============================================================================\n7. LANE A — ПЕРВАЯ ЗАДАЧА, КОТОРУЮ МОЖНО ДЕЛАТЬ ПАРАЛЛЕЛЬНО\n===============================================================================\n\nLane A НЕ должен ждать Lane B, чтобы начать design.\n\nОн может сразу:\n\n1. перечитать:\n APPLY3\n CONTRACTAST1\n IMPORTDISC2\n REBUILDHELP1\n\n2. перечитать:\n /etc/pve/HOMELAB_ASSISTANT_ERROR_REGISTER.md\n /etc/pve/31_HOMELAB_REFERENCE.md\n\n3. найти authoritative NEWFI Git worktree / branch / Portal200 deployment source.\n\n4. построить APPLY4 carrier OFFLINE / PREP ONLY.\n\n5. В APPLY4 заранее исправить:\n - result contract;\n - official XenForo rebuild path;\n - fail-closed prestate;\n - explicit rollback semantics;\n - exact mutation accounting;\n - exact COMMAND_ID;\n - publication/readback.\n\n6. Не запускать APPLY4 mutation, пока Lane B не подтвердил current-state eligibility.\n\n===============================================================================\n8. APPLY4 — ЧТО ДОЛЖНО БЫТЬ В ДИЗАЙНЕ\n===============================================================================\n\nAPPLY4 не должен быть слепым rerun APPLY3.\n\nОбязательные свойства:\n\nA. PRESTATE\n- authority checks;\n- runner SHA;\n- exact Git local/remote/clean;\n- exact expected source bytes/hashes;\n- exact current Portal add-on state;\n- services healthy;\n- target environment identity;\n- no unexplained post-APPLY3 drift.\n\nB. ADD-ON IMPORT / REBUILD\n- use native XenForo command:\n xf:addon-rebuild \n- use -f only if evidence/design shows it is needed;\n- do not return to manual PHP import loop.\n\nC. RESULT CONTRACT\nMust match runner schema exactly.\nAt minimum:\n- supported version;\n- exact command_id;\n- status in OK/BLOCKED/FAIL;\n- changes_made boolean;\n- rollback fields with correct types.\nDo not emit unknown where boolean is required.\n\nD. FAIL CLOSED\nIf prestate is not exact:\nBLOCKED / no mutation.\n\nE. ROLLBACK\nBefore mutation:\n- prove rollback target/material exists;\n- preserve previous product/app state;\n- rollback on any failed verification;\n- verify rollback result.\n\nF. VERIFICATION\nAfter candidate:\n- XenForo CLI exit;\n- add-on version/state;\n- relevant DB rows read-only;\n- routes;\n- services;\n- XenForo error log;\n- no unexpected file drift.\n\nG. GIT\nIf Git promotion belongs in this Portal200 stage:\n- one writer;\n- explicit path staging;\n- git diff --check;\n- no git add .;\n- no reset --hard;\n- no git clean -fd;\n- no force push;\n- verify local == remote after push.\n\nH. PUBLICATION\nExact runtime/history/.txt must be readable and match COMMAND_ID.\n\n===============================================================================\n9. ЧТО НЕЛЬЗЯ ДЕЛАТЬ\n===============================================================================\n\n- Не считать APPLY3 успешным.\n- Не считать APPLY3 rollback успешным.\n- Не reuse APPLY3 ID.\n- Не запускать raw SQL mutation.\n- Не запускать manual PHP import loop, пока native rebuild доказан.\n- Не hardcode add-on ID без live/source evidence.\n- Не делать git reset --hard.\n- Не делать git clean -fd.\n- Не force push.\n- Не запускать два writer.\n- Не принимать generic latest как authoritative без exact COMMAND_ID.\n- Не использовать KOW VM/IP/path как NEWFI environment.\n- Не переносить KOW product state в NEWFI.\n\n===============================================================================\n10. WINDOWS / SSH TRANSPORT — ПЕРЕИСПОЛЬЗУЕМ ИЗ KOW\n===============================================================================\n\nPlink:\nC:\\Program Files\\PuTTY\\plink.exe\n\nPageant:\nC:\\Program Files\\PuTTY\\pageant.exe\n\nSSH key:\n\\Documents\\ssh\\homelab_ed25519.ppk\n\nEncrypted PPK.\n\n\nNormal transport:\n\nCMD\n -> PowerShell 5.1\n -> Start-Process\n -> Plink -batch -agent -ssh -P 22 -m \n -> root@\n -> pve01\n -> direct read-only bridge OR homelab-chat-run\n -> Gitea runtime publication\n -> exact immutable readback\n\nDo not use:\n- MobaXterm;\n- -i in normal carrier;\n- pause;\n- Notepad;\n- blind host-key acceptance.\n\nPowerShell:\nseparate stdout/stderr;\n-NoNewWindow;\n-Wait;\n-PassThru;\nreal ExitCode.\n\nRemote command file:\nUTF-8 no BOM;\none physical line;\nSHA verified.\n\nLarge payload:\nzlib + base64;\nSHA256;\npython3 -I -B.\n\n===============================================================================\n11. AUTHORITY CHECKS\n===============================================================================\n\nПеред серьёзной server command:\n\n/etc/pve/HOMELAB_ASSISTANT_ERROR_REGISTER.md\n/etc/pve/31_HOMELAB_REFERENCE.md\n\nОба:\nreadable;\nnonempty;\nпрочитать.\n\nVisibly emit:\n\nERROR_REGISTER_CHECK=OK\nREFERENCE_CHECK=OK\nAUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED\n\nFail -> STOP.\n\n===============================================================================\n12. GITEA READBACK\n===============================================================================\n\nAuthoritative:\n\nhttps://git.gram1.ru/homelab-admin/homelab-public-context/raw/branch/assistant-runtime/runtime/history/.txt\n\nJSON, если нужен:\n\nhttps://git.gram1.ru/homelab-admin/homelab-public-context/raw/branch/assistant-runtime/runtime/history/.json\n\nНельзя делать вывод по runtime/latest.txt,\nесли COMMAND_ID не совпадает.\n\n===============================================================================\n13. КАК СИНХРОНИЗИРОВАТЬ ДВА ЧАТА\n===============================================================================\n\nПосле каждого accepted checkpoint:\n\n1. чат публикует exact COMMAND_ID;\n2. второй чат читает immutable Gitea history;\n3. оба обновляют общий current-state;\n4. FAIL/RCA не считать product progress;\n5. PASS read-only может закрывать audit/preflight;\n6. mutation checkpoint только Lane A.\n\nЕсли Lane A сделал change:\nLane B перед следующим audit обязан заново прочитать этот exact checkpoint.\n\nЕсли Lane B обнаружил HOLD:\nLane A не запускает mutation до разбора HOLD.\n\n===============================================================================\n14. PROMPT ДЛЯ ЧАТА A — SINGLE WRITER\n===============================================================================\n\nТы LANE A / SINGLE WRITER для NEWFI Portal200.\n\nИспользуй Gitea assistant-runtime как machine truth.\nНе занимайся KingOfWolk: KOW CSP agreed stage уже CLOSED.\n\nCurrent NEWFI checkpoints:\n- APPLY3 FAIL, invalid result contract, mutation outcome UNKNOWN.\n- CONTRACTAST1 OK read-only.\n- IMPORTDISC2 OK read-only.\n- REBUILDHELP1 OK read-only.\n- native XenForo command xf:addon-rebuild [options] подтверждён.\n\nТвоя задача:\nпараллельно с Lane B спроектировать NEWFI Portal200 APPLY4,\nно НЕ запускать mutation, пока Lane B не вернёт\nELIGIBLE_FOR_PORTAL200_APPLY4_PREP.\n\nAPPLY4:\n- новый unique COMMAND_ID family NEWFI-260907-A-PORTAL200-...\n- exact authority checks;\n- current-state preconditions;\n- correct homelab-chat-run result contract;\n- native xf:addon-rebuild with exact live-confirmed add-on ID;\n- fail closed;\n- rollback proof;\n- verification;\n- single writer;\n- exact Gitea publication/readback.\n\nПеред каждой реальной mutation заново прочитай последние Lane A + Lane B checkpoints.\n\n===============================================================================\n15. PROMPT ДЛЯ ЧАТА B — READ-ONLY AUDITOR\n===============================================================================\n\nТы LANE B / STRICT READ-ONLY AUDITOR для NEWFI Portal200.\n\nНикаких Git/application/DB/production mutations.\n\nИспользуй proven bridge:\ndirect read-only phase outside homelab-chat-run;\nserialized sanitized publication through runner.\n\nCOMMAND_ID family:\nNEWFI-260907-B-PORTAL200-...\n\nСразу выполни post-APPLY3 current-state recovery audit:\n\n- authority checks;\n- runner SHA + contract;\n- authoritative Git local/remote/clean;\n- exact NEWFI staging/prod identity;\n- exact XenForo docroot/version;\n- exact Portal Add-On ID;\n- installed/version/rebuildable state;\n- APPLY3 aftermath;\n- file/source hashes;\n- service health;\n- relevant HTTP routes;\n- XF error log state;\n- read-only DB evidence;\n- no mutation.\n\nFinal decision:\nELIGIBLE_FOR_PORTAL200_APPLY4_PREP\nor exact HOLD_...\n\nПубликуй bounded sanitized evidence в immutable Gitea history.\nПосле публикации сообщи exact COMMAND_ID.\n\n===============================================================================\n16. РЕКОМЕНДУЕМЫЙ СТАРТ СЕЙЧАС\n===============================================================================\n\nЛучший быстрый порядок:\n\nNOW:\n- текущий чат = Lane A;\n- новый второй чат = Lane B.\n\nОдновременно:\nLane A готовит APPLY4 design.\nLane B снимает current-state recovery audit.\n\nКогда Lane B PASS:\nLane A сверяет immutable evidence и запускает единственный change APPLY4.\n\nПосле APPLY4:\nLane B выполняет независимый read-only post-change verification,\nесли это реально добавляет evidence и не дублирует уже встроенный rollback/canary.\n\n===============================================================================\n17. COUNTER / ROADMAP\n===============================================================================\n\nНе использовать KingOfWolk counter.\nУ KOW counter = 0 и scope закрыт.\n\nДля NEWFI ранее использовалась рабочая оценка оставшихся команд,\nно её нельзя считать authoritative runtime state без восстановления NEWFI roadmap.\n\nПервый Lane B recovery audit должен также найти/проверить текущую NEWFI roadmap/\naccepted-stage count, если он хранится в repo/reference.\n\nДо этого не печатать ложный точный countdown.\n\n===============================================================================\n18. SOURCE-OF-TRUTH PRIORITY\n===============================================================================\n\nПри конфликте:\n\n1. /etc/pve/HOMELAB_ASSISTANT_ERROR_REGISTER.md\n2. /etc/pve/31_HOMELAB_REFERENCE.md\n3. exact immutable Gitea runtime/history/.txt\n4. authoritative Git source/current live state\n5. этот handoff\n\nЭтот handoff ускоряет старт, но не перекрывает более свежий live/Gitea evidence.\n\n===============================================================================\nAPPENDIX A\nПОЛНЫЙ HANDOFF ИЗ ВТОРОГО ЧАТА: KINGOFWOLK CSP\n(сохранён целиком; используется для operational/concurrency rules, не как NEWFI product-state)\n===============================================================================\n\n\nПОЛНЫЙ HANDOFF: KINGOFWOLK CSP\nДата контекста: 2026-09-07\n\n1. СТАТУС ПРОЕКТА НА МОМЕНТ HANDOFF\n\nПроект: KingOfWolk forum CSP.\n\nShared counter:\n0 команд до полного финиша.\n\nВажно: 0 означает, что согласованный безопасный CSP-stage полностью завершён и подтверждён evidence. Это не означает, что CSP доведён до теоретически максимальной жёсткости.\n\nОтдельно оставлены будущие hardening-задачи:\n- удаление style-src 'unsafe-inline';\n- рефакторинг существующего javascript: URL;\n- перевод script-src-elem из Report-Only в enforcing после достаточного периода наблюдения.\n\nФинальный accepted checkpoint:\n\nKOW-260907-A-FINAL1\nSTATUS=OK\nRC=0\nDECISION=KINGOFWOLK_CSP_AGREED_STAGE_FINAL_EVIDENCE_CLOSED\n\nФинальный canary не внёс изменений в production.\n\n\n2. CANONICAL KINGOFWOLK ENVIRONMENT\n\nФорум:\n\nDomain:\nhttps://kingofwolk.ru\n\nForum VM:\nVM160\nhost: pve02\nIP: \n\nXenForo:\n2.3.12\nXF id: 2031270\n\nDatabase:\nxf_kingofwolk\n\nDocument root:\n/var/www/forums/kingofwolk/public\n\nXF source:\n/var/www/forums/kingofwolk/src/XF\n\nИз ранее принятого baseline:\n\nboardActive = 1\nboard title = KingOfWolk\nstyle id = 2\nstyle name = KingOfWolk Dark\n\nCAPTCHA = Cloudflare Turnstile\nfriendly URLs = enabled\nthird-party add-ons = none\n\nusers = 2\nadmins = 1\nnodes = 13\nthreads = 73\nposts = 73\nattachments = 0\nXF errors = 0\n\nOrigin-side services были healthy:\n\nNginx\nMariaDB\nphp8.3-fpm\n\nCSP реализуется на edge, а не origin XenForo.\n\n\n3. EDGE / NPMPLUS\n\nEdge находится на:\n\nVM130\nhost: pve03\n\nNPMplus:\n\ncontainer: npmplus\nimage: zoeyvid/npmplus:2026-06-17-b1\n\nLive KingOfWolk proxy config:\n\n/opt/npmplus/nginx/proxy_host/996.conf\n\nMetadata:\n\nowner: root:root\nmode: 0644\n\nCSP collector log:\n\n/opt/npmplus/csp-reports/kingofwolk-csp-report.log\n\nLog metadata:\n\nroot:root\n0600\n\nDirectory:\n\n0700\n\nCollector endpoint:\n\n/__csp-report-v1\n\nSemantics:\n\nGET -> 405\nAllow -> POST\n\nCollector поддерживает:\n\napplication/csp-report\napplication/reports+json\napplication/json\n\nCollector sanitizes:\n- script-sample;\n- query/fragment у URI.\n\nRotation threshold:\n\n>= 5 MiB\n\nФинальный canary снова подтвердил:\n\ncollector GET = 405\nAllow = POST\n\n\n4. GIT — AUTHORITATIVE SOURCE\n\nИспользуемый repo:\n\nhomelab-admin/homelab-ops\n\nИзолированный CSP worktree:\n\n/root/kingofwolk-csp-baseline-20260907\n\nBranch:\n\nforum/kingofwolk-csp-baseline-20260907\n\nНе использовать /srv/homelab-ops для изменений KingOfWolk CSP.\nИсторически он был dirty/diverged и использовался только как reference.\n\nClone-local Git identity:\n\nuser.name = homelab-ops-bootstrap\nuser.email = root@pve01.gram1.ru\n\nТекущий финальный accepted HEAD:\n\n6f584c5faa76d0067b08977aeb583fa0e4de14aa\n\nParent:\n\n3e5d8584ae6887c292cc910c5796e73d8d20aecd\n\nCommit message:\n\ncsp(kingofwolk): stage script nonce and enforce font media\n\nТекущий source file:\n\ndeploy/forums/kingofwolk/edge/996.conf\n\nТекущий source SHA / production edge SHA:\n\n458c2cf0763e4790f7d2d3757efd883b25813a31aab4e8dce6f785b8dea48a6e\n\nФинальный canary подтвердил:\n\nGit local HEAD = 6f584c5faa76d0067b08977aeb583fa0e4de14aa\nGit remote HEAD = 6f584c5faa76d0067b08977aeb583fa0e4de14aa\nworktree clean = true\n\nИ edge до/после финального canary оставался:\n\n458c2cf0763e4790f7d2d3757efd883b25813a31aab4e8dce6f785b8dea48a6e\n\n\n5. ИСТОРИЯ ACCEPTED GIT CSP COMMITS\n\nПоследовательность основных accepted commits:\n\n6908d4ebf2552244a68e3c0990fdc3a219c05d2c\ninitial CSP baseline docs\n\nf8d1ae6981df35f25d09a41392bc0a26742b7f38\nJoyPixels Report-Only allowance\n\n34f9c76c5cbf81f9cdf7f50d1ac501cf870abc9c\nminimal structural enforcement source\n\nc7a8a68a74fd3eb74cfb708b6bd3b866159b4899\ncsp(kingofwolk): enforce same-origin form submissions\n\nЕго source SHA:\n\n834973af57263b326ca6aee52b2ecb3fa2cf0fb486e5a77a62d4210395b8d9c3\n\nСледующий:\n\ne4635c9997801a0ea65aad727270c88ee3bdb817\ncsp(kingofwolk): enforce PWA self sources\n\nSource SHA:\n\n28e855ff56c4844768f0e8606fe0edc2acb3f548a5c06fa15c0d80ae00e2bc1b\n\nСледующий:\n\n3e5d8584ae6887c292cc910c5796e73d8d20aecd\ncsp(kingofwolk): enforce image and network sources\n\nSource SHA:\n\nfc9fb1dbdb6141bfb43a8122dcf3db435a94da48d0a0c02fe9dfae019b1439c5\n\nФинальный текущий commit:\n\n6f584c5faa76d0067b08977aeb583fa0e4de14aa\ncsp(kingofwolk): stage script nonce and enforce font media\n\nSource SHA:\n\n458c2cf0763e4790f7d2d3757efd883b25813a31aab4e8dce6f785b8dea48a6e\n\n\n6. ТЕКУЩИЙ PRODUCTION ENFORCING CSP\n\nФинальный enforcing CSP:\n\nbase-uri 'self';\nobject-src 'none';\nframe-ancestors 'self';\nform-action 'self';\nworker-src 'self';\nmanifest-src 'self';\nimg-src 'self' data: blob: https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/;\nconnect-src 'self' https://challenges.cloudflare.com;\nframe-src 'self' https://challenges.cloudflare.com;\nfont-src 'self' data:;\nmedia-src 'self';\n\nВ одной строке:\n\nbase-uri 'self'; object-src 'none'; frame-ancestors 'self'; form-action 'self'; worker-src 'self'; manifest-src 'self'; img-src 'self' data: blob: https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/; connect-src 'self' https://challenges.cloudflare.com; frame-src 'self' https://challenges.cloudflare.com; font-src 'self' data:; media-src 'self';\n\nЧто намеренно НЕ enforcing:\n\ndefault-src\nscript-src\nscript-src-elem\nscript-src-attr\nstyle-src\nstyle-src-elem\nstyle-src-attr\n\nТакже enforcing policy не содержит:\n\n'unsafe-inline'\n'unsafe-eval'\n\nЭто намеренно: script/style hardening ещё не переведён в production enforcement.\n\n\n7. ТЕКУЩИЙ PRODUCTION REPORT-ONLY CSP\n\nSource-template на edge содержит Nginx variable $request_id.\n\nЛогическая policy:\n\ndefault-src 'self';\nbase-uri 'self';\nobject-src 'none';\nframe-ancestors 'self';\nform-action 'self';\n\nscript-src 'self' 'unsafe-inline' https://challenges.cloudflare.com;\n\nscript-src-elem\n 'self'\n 'nonce-$request_id'\n https://challenges.cloudflare.com;\n\nstyle-src 'self' 'unsafe-inline';\n\nimg-src\n 'self'\n data:\n blob:\n https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/;\n\nfont-src 'self' data:;\n\nconnect-src\n 'self'\n https://challenges.cloudflare.com;\n\nframe-src\n 'self'\n https://challenges.cloudflare.com;\n\nworker-src 'self';\nmanifest-src 'self';\nmedia-src 'self';\n\nreport-uri /__csp-report-v1;\n\nТочная source-строка:\n\ndefault-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; form-action 'self'; script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com; script-src-elem 'self' 'nonce-$request_id' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/; font-src 'self' data:; connect-src 'self' https://challenges.cloudflare.com; frame-src 'self' https://challenges.cloudflare.com; worker-src 'self'; manifest-src 'self'; media-src 'self'; report-uri /__csp-report-v1;\n\nПри HTTP response $request_id уже заменён Nginx на фактический per-request nonce.\n\n\n8. NGINX NONCE TRANSPORT\n\nТекущий source также содержит transport для nonce-инъекции.\n\nКлючевые строки:\n\nproxy_set_header Accept-Encoding \"\";\nsub_filter_once off;\nsub_filter ' tag.\n\n\n9. ФИНАЛЬНЫЙ NONCE EVIDENCE\n\nФинальный checkpoint:\n\nKOW-260907-A-FINAL1\n\nпроверил HTML маршруты дважды:\n\n/\n /login/\n /register/\n /help/smilies/\n /threads/dobro-pozhalovat-na-ofitsial-nyi-forum-kingofwolk.1/\n\nДля каждого запроса проверялось:\n\nHTTP = 200\nровно один nonce в CSP Report-Only\nnonce не содержит literal $\nnonce имеет допустимый формат\nкаждый