Files
booth/tests/mutations/r2_flow.toml
T
vh 704e8cd809 fix(desk): the heid bug-hunt panel on the row controls (round "Slate", 4/4)
- Touch: on a coarse pointer every row control is at least 28px square
  again (32px), and wipe stands clear of the zip link. The move onto the
  facts line had dropped the deliberate 28px floor to ~21px, 4-6px from
  zip; with scripts off no confirm fires, so a mis-tap on wipe is the
  delete. The zip link no longer breaks between its glyph and its word,
  and each separator is glued to the item after it.
- The wipe dialog shows the name as it should be read: control and bidi
  formatting characters in an agent-made name show as U+FFFD, so U+202E
  or a newline cannot rewrite what the operator approves. An unknown
  data-confirm word now prompts generically instead of submitting
  unguarded (fail closed).
- No page scrolls sideways: `code` wraps anywhere, so a long unbreakable
  install path in the footer or the empty Desk no longer widens every
  page. The overflow test now sweeps 390/720/850/1000/1400 with the
  heaviest row the Desk draws, and compares scrollWidth with the page's
  own clientWidth.

Its first fixture used a hyphenated path, which wrapped by itself; the
test passed with the bug present until the path became one unbreakable
run. r2_flow.toml: 27/27 proved. 749 passed.
2026-09-23 11:27:34 -07:00

246 lines
9.7 KiB
TOML

# R2 — the review flow: falsifiers the round claims, and the change each forbids.
#
# Every row was proved RED under its mutation in the session that wrote it,
# then committed here so the proof is an artifact rather than scrollback. The
# browser rows need the Playwright Chromium the browser tests already use.
#
# Deliberately ABSENT: single guards inside a defence in depth, each of which
# stays green when removed alone because another layer still holds — so a row
# for any one of them would be a vacuous proof, and this table's own first run
# said so. `.seen`'s O_NOFOLLOW, O_NONBLOCK and S_ISREG (the FIFO/symlink test
# covers them together); and `flagged_targets`' `error is None`, since
# hydration already strips the target from a damaged mark.
#
# The serialization row is only a falsifier because its test HOLDS the first
# refresh in the client: localhost alone never lost the race, and the first
# draft of that test stayed green with serialization deleted.
unit = "the Desk, the lightbox, the review, and the in-place client"
[[mutation]]
label = 'C1 ordinals count from 0, not 1'
file = "booth/items.py"
test = "tests/test_flow.py::test_a_filtered_tile_keeps_its_number_in_the_whole_set"
old = '''ordinal=len(items) + 1,'''
new = '''ordinal=len(items),'''
[[mutation]]
label = 'C2 .seen: a nested-too-deep marker escapes the never-raises read'
file = "booth/items.py"
test = "tests/test_flow.py::test_a_deeply_nested_seen_marker_reads_as_nothing_seen"
old = '''except (UnicodeDecodeError, ValueError, RecursionError):'''
new = '''except (UnicodeDecodeError, ValueError):'''
[[mutation]]
label = 'C3 a non-finite q is accepted as a q-value'
file = "booth/app.py"
test = "tests/test_flow.py::test_a_non_finite_q_is_malformed"
old = ''' raise ValueError("non-finite q")'''
new = ''' pass'''
[[mutation]]
label = 'C3 204 on an explicit JSON Accept becomes the 303'
file = "booth/app.py"
test = "tests/test_flow.py::test_an_explicit_json_accept_gets_204_and_the_write_still_lands"
old = ''' return Response(status_code=204)'''
new = ''' pass'''
[[mutation]]
label = 'C3 back=view lands on the review for a doc too (ring check dropped)'
file = "booth/app.py"
test = "tests/test_flow.py::test_back_view_lands_on_the_review_only_for_a_media_item"
old = ''' if f in ring:'''
new = ''' if True:'''
[[mutation]]
label = 'C4 the Desk counts orphan flags'
file = "booth/app.py"
test = "tests/test_flow.py::test_a_flag_on_a_file_that_is_gone_stays_visible_and_withdrawable"
old = '''"flags": len(flagged_targets(marks) & {it.rel for it in items}),'''
new = '''"flags": len(flagged_targets(marks)),'''
[[mutation]]
label = 'C4 landed_at follows symlinks'
file = "booth/app.py"
test = "tests/test_flow.py::test_the_content_clock_reads_the_booth_not_what_its_links_point_at"
old = ''' st = p.lstat()'''
new = ''' st = p.stat()'''
[[mutation]]
label = 'C4 one unreadable entry reads the whole booth as landed NOW'
file = "booth/app.py"
test = "tests/test_flow.py::test_one_unreadable_entry_costs_that_entry_not_the_booth"
old = '''pin it in "new" forever.
continue'''
new = '''pin it in "new" forever.
return time.time()'''
[[mutation]]
label = 'C4 a non-web bookmark URL becomes a link'
file = "booth/templates/index.html"
test = "tests/test_flow.py::test_the_desk_never_makes_a_non_web_url_clickable"
old = '''{% set web = e.url.lower().startswith(('http://', 'https://')) %}'''
new = '''{% set web = true %}'''
[[mutation]]
label = 'C4 a non-web bench URL becomes a link'
file = "booth/templates/index.html"
test = "tests/test_flow.py::test_the_desk_never_makes_a_non_web_url_clickable"
old = '''{% set web = b.url.lower().startswith(('http://', 'https://')) %}'''
new = '''{% set web = true %}'''
[[mutation]]
label = 'C5 audio/video tiles lose their review link'
file = "booth/templates/booth.html"
test = "tests/test_flow.py::test_a_sound_only_booth_can_open_the_review"
old = '''{% if it.kind in ('video', 'audio') %}<a class="rv-link"'''
new = '''{% if false %}<a class="rv-link"'''
[[mutation]]
label = 'C6 a NUL in ?f escapes as a 500'
file = "booth/app.py"
test = "tests/test_flow.py::test_a_nul_in_the_review_path_is_a_404_not_a_500"
old = ''' except (OSError, ValueError):
# ValueError: an embedded NUL.'''
new = ''' except OSError:
# ValueError: an embedded NUL.'''
[[mutation]]
label = 'C3 client: no busy guard (a double-click writes twice)'
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_an_unsaved_choice_survives_a_save_elsewhere_and_a_double_click_writes_once"
old = ''' if (form.__busy) return;
'''
new = ''''''
[[mutation]]
label = 'C3 client: an unsent radio is not carried across a swap'
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_an_unsaved_choice_survives_a_save_elsewhere_and_a_double_click_writes_once"
old = ''' if (el.checked !== el.defaultChecked) t.checked = el.checked;'''
new = ''''''
[[mutation]]
label = 'C3 client: saves are not serialized'
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_quick_successive_flags_all_show"
old = ''' queue = queue.then(function () { return run(form, data); })'''
new = ''' queue = run(form, data)'''
[[mutation]]
label = 'C3 the standalone marks page has no region'
file = "booth/templates/marks.html"
test = "tests/test_flow_browser.py::test_the_standalone_marks_page_updates_in_place"
old = '''<div class="marks-panel" data-region="marks-panel">'''
new = '''<div class="marks-panel">'''
[[mutation]]
label = "C6 the next arrow's rail offset applies at phone width"
file = "booth/templates/view.html"
test = "tests/test_flow_browser.py::test_the_next_arrow_clears_the_rail_only_beside_it"
old = ''' .vprev{left:0}.vnext{right:0}
@media (min-width:901px){.vnext{right:360px}}
'''
new = ''' .vprev{left:0}.vnext{right:360px}
'''
[[mutation]]
label = "resolver: an entry that cannot be stat'd raises out of booth_items"
file = "booth/items.py"
test = "tests/test_items.py::test_a_folder_that_lists_but_cannot_be_searched_costs_its_files_not_the_index"
old = '''
if not p.is_file():
continue
except OSError:
continue'''
new = '''
if not p.is_file():
continue
except FileNotFoundError:
continue'''
[[mutation]]
label = "Desk row controls hidden until hover again (opacity 0 keeps their box)"
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_a_rows_keep_release_and_wipe_take_no_room_of_their_own"
old = '''
.desk-facts form{display:inline;margin:0}'''
new = '''
.desk-facts form{display:inline;margin:0;opacity:0}'''
[[mutation]]
label = "Desk row renders its side column with no badge in it (a reserved gap)"
file = "booth/templates/index.html"
test = "tests/test_flow_browser.py::test_a_rows_keep_release_and_wipe_take_no_room_of_their_own"
old = '''
{% if b.marks_open or b.hold == "unreadable" or section == 'new' or b.uploaded %}
<div class="desk-side">'''
new = '''
{% if true %}
<div class="desk-side">'''
[[mutation]]
label = "the stacked Desk column is a bare 1fr (content sets its minimum)"
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_the_desk_never_scrolls_sideways_at_any_width"
old = '''
@media (max-width:1000px){.desk{grid-template-columns:minmax(0,1fr)}}'''
new = '''
@media (max-width:1000px){.desk{grid-template-columns:1fr}}'''
[[mutation]]
label = "a long unbreakable install path in <code> scrolls the page sideways"
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_the_desk_never_scrolls_sideways_at_any_width"
old = '''
padding:1px 6px;border-radius:var(--radius-sm);border:1px solid var(--border-subtle);overflow-wrap:anywhere}'''
new = '''
padding:1px 6px;border-radius:var(--radius-sm);border:1px solid var(--border-subtle)}'''
[[mutation]]
label = "the row's text column cannot shrink (the 700-1000px window overflows)"
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_the_desk_never_scrolls_sideways_at_any_width"
old = '''
.desk-main{flex:1 1 auto;min-width:0}'''
new = '''
.desk-main{flex:1 1 auto}'''
[[mutation]]
label = "a coarse pointer gets the compact ~21px controls"
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_on_a_touch_screen_the_row_controls_keep_their_tap_floor"
old = '''
.desk-facts form button{min-height:32px;min-width:32px;padding:0 10px;margin-left:6px;vertical-align:middle}'''
new = '''
.desk-facts form button{padding:0 10px;margin-left:6px;vertical-align:middle}'''
[[mutation]]
label = "the zip link may break between its glyph and its word"
file = "booth/templates/base.html"
test = "tests/test_flow_browser.py::test_on_a_touch_screen_the_row_controls_keep_their_tap_floor"
old = '''
.desk-facts .dl-link{white-space:nowrap}'''
new = '''
.desk-facts .dl-link{}'''
[[mutation]]
label = "the wipe dialog shows the agent-made name raw (bidi, newline)"
file = "booth/templates/index.html"
test = "tests/test_flow_browser.py::test_the_wipe_dialog_shows_what_is_being_wiped_and_never_fails_open"
old = '''
if (!confirm(word(shown(form.getAttribute('data-booth') || '')))) ev.preventDefault();'''
new = '''
if (!confirm(word(form.getAttribute('data-booth') || ''))) ev.preventDefault();'''
[[mutation]]
label = "an unknown data-confirm word submits with no prompt (fail open)"
file = "booth/templates/index.html"
test = "tests/test_flow_browser.py::test_the_wipe_dialog_shows_what_is_being_wiped_and_never_fails_open"
old = '''
var word = WORDS[form.getAttribute('data-confirm')] || ASK;
if (!confirm('''
new = '''
var word = WORDS[form.getAttribute('data-confirm')];
if (word && !confirm('''