{"v":"<h2 id=\"user-content-where-this-stands-today\" dir=\"auto\">Where this stands today<\/h2>\n<p dir=\"auto\">Most of the safety rule is already in place on the server. It runs in the same transaction as the save:<\/p>\n<ul dir=\"auto\">\n<li><strong>A changed answer withdraws the generated forms and every signature on them.<\/strong> In <code>form_v2_visit_save()<\/code> (<code>code\/form_v2_visit.inc.php<\/code>), any accepted change calls <code>form_v2_visit_supersede_candidates()<\/code>. The candidate becomes <code>superseded<\/code>, and every tap on it stops counting. The taps are kept as the record. An unchanged answer is not counted as a change, so re-saving the same value withdraws nothing.<\/li>\n<li><strong>Nothing can be signed against old copies.<\/strong> Every sign, adopt and finish request checks <code>form_v2_candidate_is_current()<\/code> under the visit lock, and a superseded printing is refused. This is pinned in <code>scripts\/test-form-v2-sign-state.php<\/code> (&#34;a change withdraws&#34;).<\/li>\n<li><strong>The forms are always generated again from the current answers.<\/strong> Signing stamps only the kept review copy, which is proved against its hash. There is no way to sign a copy that does not match the answers.<\/li>\n<li><strong>A signed visit takes no more answers<\/strong> (<code>closed<\/code> \/ <code>signed<\/code> refusal).<\/li>\n<\/ul>\n<p dir=\"auto\">What is missing is all on the person&#39;s side:<\/p>\n<ol dir=\"auto\">\n<li><strong>No warning before the change.<\/strong> The page says <em>afterwards<\/em>: &#34;An answer changed after the forms were generated, so those copies, and the signatures on them, were withdrawn.&#34; By then the signatures are already gone.<\/li>\n<li><strong>Later sections are not flagged<\/strong> when the change reveals new questions in them. That is #166, and I&#39;d build it there (see that issue) rather than twice.<\/li>\n<li><strong>A signed visit cannot be corrected at all.<\/strong> That needs amendments (FormsV2Plan \u00a78.5), which are not built.<\/li>\n<\/ol>\n<h2 id=\"user-content-proposed-plan\" dir=\"auto\">Proposed plan<\/h2>\n<p dir=\"auto\"><strong>A. Lock the answers once forms are generated, and confirm before unlocking<\/strong> (the modal from the comment above).\nWhile a current printing exists, the questions show read-only, with a <strong>Change an answer<\/strong> button. That button opens a modal:<\/p>\n<blockquote>\n<p dir=\"auto\">The forms have been generated <em>(and N lines have been signed)<\/em>. Changing an answer withdraws these copies and their signatures. You will generate the forms again, and everyone signs again.\n<strong>[Change answers]  [Keep the forms]<\/strong><\/p>\n<\/blockquote>\n<p dir=\"auto\">I&#39;d use a lock rather than catching the first keystroke. The answers autosave as they are typed, so a modal fired by an <code>input<\/code> event would interrupt typing and is easy to dismiss by accident. Unlocking withdraws nothing by itself. Only the first actual saved change does, so a person who unlocks and then changes nothing keeps the forms.<\/p>\n<p dir=\"auto\"><strong>B. Enforce the confirmation on the server, not only in the page.<\/strong>\nWhile a current candidate exists, a save must carry <code>withdraw_candidate = &lt;pk&gt;<\/code> naming it. Otherwise it is refused with code <code>printed<\/code> (and the page shows the modal). This stops a stale tab, a retried request or a future client from silently wiping 36 signatures. The lease already allows only one writing window, so this is a second guard, not the only one.<\/p>\n<p dir=\"auto\"><strong>C. After the change, say what to do next.<\/strong> Keep the existing withdrawal notice. Add, once #166 exists, &#34;New questions appeared in: <em>Emergencies<\/em>, <em>Coordination of Care<\/em>&#34; with links. The Generate button stays available, but see question 3.<\/p>\n<p dir=\"auto\"><strong>D. Tests:<\/strong> a save without the acknowledgement is refused while a candidate is current and accepted when there is none. A save with an acknowledgement naming an old candidate is refused as stale.<\/p>\n<h2 id=\"user-content-questions\" dir=\"auto\">Questions<\/h2>\n<ol dir=\"auto\">\n<li><strong>Does any change withdraw everything?<\/strong> Today it does: one typo in a notes field means a new printing and every line signed again. The plan (\u00a76) chose that for the first release. The alternative is to keep the taps on forms whose generated copy is <strong>byte-identical<\/strong> to the one that was signed, so only the forms the change actually reached need signing again. That is safe because a tap is bound to the copy&#39;s hash, but the candidate digest currently binds the whole set, so it is a real change. <strong>My recommendation: keep &#34;everything again&#34; for the pilot, and revisit if staff complain.<\/strong><\/li>\n<li><strong>Is correcting a <em>signed<\/em> visit in scope here, or a separate issue?<\/strong> That is amendments (\u00a78.5): a new revision, the old signed copies kept, new copies signed. I&#39;d make it its own issue, after submission.<\/li>\n<li><strong>Should Generate forms be blocked while a section has new questions nobody has opened<\/strong> (#166)? Or should it warn and allow? I lean towards <strong>block<\/strong>, because the answers are printed exactly as they stand.<\/li>\n<\/ol>\n"}