{"v":"<p dir=\"auto\"><strong>Built (2026-10-05), not yet committed.<\/strong><\/p>\n<p dir=\"auto\"><code>form_v2_publish_check()<\/code> (pure, <code>code\/form_v2_review.inc.php<\/code>) is built on the Form Explorer&#39;s model, and three places read it: the Explorer&#39;s <strong>Gaps<\/strong> tab, the CLI (#127) and the new review page. A publish is refused unless all nine checks pass:<\/p>\n<ol dir=\"auto\">\n<li>publish rules<\/li>\n<li>required boxes are asked<\/li>\n<li>every box is filled, or blank for a written reason<\/li>\n<li>no orphan questions<\/li>\n<li>every branch reachable<\/li>\n<li>bindings<\/li>\n<li>paper coverage<\/li>\n<li>every shared answer has a ruling<\/li>\n<li><strong>every form prints a proof<\/strong>, using the same rule a kept form uses<\/li>\n<\/ol>\n<p dir=\"auto\">The Gaps tab does not render proofs, so it shows that check as &#34;not run&#34;, which never counts as a pass.<\/p>\n<p dir=\"auto\"><strong>Review page <code>\/admin\/form-v2-publish<\/code><\/strong> (menu: <em>Publish an Interview<\/em>) shows:<\/p>\n<ul dir=\"auto\">\n<li>the verdict and the check;<\/li>\n<li>what publishing does;<\/li>\n<li>what changed: questions new, reworded (old and new side by side), moved, asked under another condition or removed, plus changes to the forms and placements;<\/li>\n<li>every question in full;<\/li>\n<li>one <strong>Publish all of this<\/strong> button (needs the Approve right).<\/li>\n<\/ul>\n<p dir=\"auto\">The page is a rollback rehearsal of the real publish. The button sends the reviewed release&#39;s fingerprint, and the publish refuses if anything changed in between. It never activates.<\/p>\n<p dir=\"auto\">SOC_AO rehearses clean today: 316 questions, all nine checks pass.<\/p>\n<p dir=\"auto\">Tests: <code>test-form-v2-review.php<\/code> (51) and <code>test-form-v2-pipeline-state.php<\/code> (19).<\/p>\n"}