fix(inplace,embed): input set back mid-flight, report inputs, ambiguous anchors

Four items owed after S5b, reported by design-dev during the anti-slop run:

- carry() measured a sent-then-changed form against its OLD DEFAULTS. An
  answer set back mid-flight to the value the page first showed read as
  untouched, and the swap put the just-saved value over it. A form sent and
  then changed is now measured against its sent snapshot (sentSet.snapOf).
- The embed's clean-batch reload saw only our own forms. A report's own
  inputs lost whatever the operator had typed into them. Unsaved text in
  any control we don't own now holds the reload, and the page says so.
- Two r2b.toml rows ("D3 a stored theme...", "D3 forced light...") matched
  twice, so they proved only by where the first match fell. Both are
  re-anchored, and scripts/mutation_check.py now refuses any anchor that
  matches more than once. A new tool control covers that.
- The r2_flow contract's C3 steps 2 and 4 now say what S5b superseded. U3
  gains the report-input rule.

Mutation rows: u3_submit_all +1, r2_submit_all +1. Four rows were
re-anchored onto the moved lines.
This commit is contained in:
vh
2026-09-28 16:52:42 -07:00
parent a22a00b82e
commit 377e652670
13 changed files with 194 additions and 32 deletions
+19 -4
View File
@@ -221,7 +221,11 @@ today's zoom flag form carries no `back`, so it lands on the gallery.
is the form's IDENTITY plus its fields as they stood at the press, never
the DOM node: a queued save whose node an earlier swap replaced is still
recognised, where a node test missed it and carried a saved note's text
back as a draft.
back as a draft. A sent form that changed after its press is carried
against what it SENT, not its old defaults (amended 2026-09-28): an
answer set back mid-flight to the value the page first showed would
otherwise read as untouched, and the swap would put the saved value over
the operator's last word.
3. **Saves are SERIALIZED.** Each save runs its POST, its GET and its swap
before the next begins, so an older snapshot never lands after a newer one
(three quick flags show three flags). A form already queued or in flight
@@ -285,11 +289,22 @@ today's zoom flag form carries no `back`, so it lands on the gallery.
`test_a_batch_whose_refresh_fails_keeps_the_page` fails; count a sent form
as sent after it changed and
`test_a_change_to_a_sent_pick_during_the_flight_is_kept` fails; count no
form as sent and `test_a_saved_notes_box_comes_back_empty` fails.
form as sent and `test_a_saved_notes_box_comes_back_empty` fails; measure
a sent-then-changed form against its old defaults and
`test_a_sent_pick_set_back_to_its_first_value_mid_flight_is_kept` fails.
4. **The script never re-POSTs.** A retry after a lost response would re-apply
the judgment: a duplicate note, or a re-dated answer.
- On a non-204 HTTP response, or a network failure, it writes a fixed
message into the page's server-rendered status element
- ⚠ **SUPERSEDED IN PART by `as_antislop.contract.md` S5b (merged
2026-09-28, `0233ca6`)**, which owns the status line and the failure
path from there on. What changed: the status line is never `hidden` (it
floats, and every save says "Saving…" / "Saved." with a warn tone for a
failure); and a failed one-form save reloads ONLY when no in-place form
holds a draft (the sent one excepted while it still equals its press),
re-checked at the beat. Otherwise it says so and keeps the page. Leaving
a page with an unsent draft asks first. What did not change: no re-POST,
ever, and the words are about the script's own requests only.
- As first written: on a non-204 HTTP response, or a network failure, it
writes a fixed message into the page's server-rendered status element
(`data-region="status"`, via textContent). After a beat (0.9 s, so the
words can be read) it reloads the page with a GET, so what you see is the
server's truth.
@@ -279,6 +279,10 @@ submit on one of our forms F:
operator entered stays on the page.
A refusal blocks the reload ON ITS OWN: a refused form set back to its
first value reads clean, and "nothing dirty" alone reloaded over it.
So does unsaved input in the REPORT'S OWN controls (amended
2026-09-28): any input, textarea or select not owned by one of our
forms that differs from its default. The reload would clear it, and
ourForms cannot see it.
```
Five consequences, each deliberate:
@@ -440,7 +444,9 @@ leave a saved form's baseline where it was and
`test_a_retry_after_a_refusal_sends_only_what_did_not_save` fails; drop the
class-level `[hidden]` rule and `test_the_empty_status_line_stays_hidden_under_host_css`
fails; let "nothing dirty" alone decide the reload and
`test_a_refusal_blocks_the_reload_even_when_nothing_reads_dirty` fails.
`test_a_refusal_blocks_the_reload_even_when_nothing_reads_dirty` fails; ignore
the report's own inputs and
`test_a_clean_batch_does_not_reload_over_text_typed_into_the_report` fails.
## Out of scope (deferred or never)