{"v":"<h2 id=\"user-content-built-fcc5d40\" dir=\"auto\">Built (fcc5d40)<\/h2>\n<p dir=\"auto\"><strong>Decisions on the three questions<\/strong><\/p>\n<ol dir=\"auto\">\n<li><strong>A question filled in from VESTA does not count as waiting<\/strong> unless it was seen and later hidden. Waiting = shown, never seen, and unanswered.<\/li>\n<li><strong>Seen, hidden, then shown again: yes, it waits again<\/strong>, even with its old answer still in it (FormsV2Plan \u00a76 reactivation review).<\/li>\n<li><strong>Waiting questions block Generate forms.<\/strong> The refusal names the sections. A Superuser&#39;s &#34;skip the check&#34; also skips this. This also answers #165 question 3.<\/li>\n<\/ol>\n<p dir=\"auto\"><strong>How it works<\/strong><\/p>\n<ul dir=\"auto\">\n<li>New table <code>form_v2_visit_seen<\/code> (<code>migrations\/20261008_visit-seen-questions.sql<\/code>). It holds question keys and dates only, no PHI. A question is <strong>seen<\/strong> once it was on screen in a section the filler then left. The page sends <code>left<\/code> (the sections it left) with its save, and that includes going to Check. The server marks what those sections showed <em>before<\/em> the save&#39;s own changes. So a question the save reveals in the section being left is still flagged. A seen question that a change hides is cleared, in the same transaction.<\/li>\n<li>The rules are pure functions in <code>form_v2_visit_rules.inc.php<\/code>: <code>form_v2_visit_is_waiting()<\/code>, <code>form_v2_visit_waiting()<\/code>, <code>form_v2_visit_seen_changes()<\/code> and <code>form_v2_visit_unseen_steps()<\/code>. <code>form_v2_visit_progress()<\/code> now returns <code>waiting<\/code> per section and overall.<\/li>\n<li>The check returns <code>unseen<\/code>. <code>form_v2_candidate_prepare()<\/code> refuses with the new code <code>unseen<\/code>, after <code>issues<\/code>.<\/li>\n<\/ul>\n<p dir=\"auto\"><strong>On screen (<code>\/visit-v2<\/code>)<\/strong><\/p>\n<ul dir=\"auto\">\n<li>The sidebar shows a dot and &#34;N new&#34; under the section count.<\/li>\n<li>Waiting questions carry a <strong>New<\/strong> label until the section is left.<\/li>\n<li>When an answer brings up questions in another section, a notice says &#34;This answer added questions in <em>Transfer and choice<\/em>&#34;, with a link.<\/li>\n<li>The Check step lists &#34;Sections with questions you haven&#39;t seen&#34; above the issues, each with a link.<\/li>\n<\/ul>\n<p dir=\"auto\"><strong>Tests:<\/strong> new cases in <code>test-form-v2-visit-rules<\/code> (233 pass), <code>test-form-v2-visit-state<\/code> (146 pass) and <code>test-form-v2-candidate-state<\/code> (64 pass). One existing case in the candidate test was adjusted: its visit had an optional question nobody had opened, so it now hit the new refusal before the &#34;no blank form&#34; one it was testing. Also checked in the browser on dev visit 75.<\/p>\n<p dir=\"auto\"><strong>To deploy:<\/strong> <code>php scripts\/migrate.php --apply<\/code>.<\/p>\n"}