fix(as-S1): the house clock — stamps read 0848, no IPs on the page
The anti-slop run (design-dev, 2026-09-28; operator: "start the fix slices") found raw ISO stamps with microseconds and offsets, the poster's IP address, and HH:MM in board rows and <time> tooltips. Operator convention 2026-09-24: a clock the operator reads is 24-hour local time as four digits, no colon. - `clock` filter: ISO (any precision, any offset), epoch, or the board's `YYYY-MM-DD HH:MM` -> `28 Sep 0848` local, year only when not this year's. Never raises; what it cannot read is shown as given. No regex (INV-3). - `byline` filter: a handle is shown, an IP address is not. Stored `by` and `answered_by` are unchanged (u2 still records the client host). - Applied to the marks' answer and memo lines, the inline ask's state tag (so the embed chrome inherits it) and the link board's row time, each in a <time> whose datetime= carries the stored value exactly. - `date_stamp` (the created/updated tooltips) renders `YYYY-MM-DD HHMM`. Folded from the heid bug-hunt (panel 4/4, thread 01M3MGPFKWBX0SJK5HFE0P3AFM): clock converts a number inside its guard (an int past float range raised, Q1); a date or ISO week renders no invented 0000 (Q8); byline also hides addr:port, [v6]:port, addr/prefix and addresses behind invisible characters (Q7); the board row's author is bylined (Q5). Refuted: Q3 (default Jinja Undefined has length 0; the test stays as a StrictUndefined guard). Accepted with reasons: Q4, Q6. Contract: docs/contracts/as_antislop.contract.md S1. Falsifiers: antislop.toml 15/15 proved (S1); all 12 tables 295/295 proved on this tree.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# The anti-slop fix slices: every falsifier the contract claims
|
||||
# (docs/contracts/as_antislop.contract.md), and the change each forbids.
|
||||
|
||||
unit = "anti-slop fix slices (the house clock, and the slices after it)"
|
||||
|
||||
# ---- S1: the house clock
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 clock renders HH:MM"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_clock_forms"
|
||||
old = ''' hhmm = time.strftime("%H%M", time.localtime(epoch))'''
|
||||
new = ''' hhmm = time.strftime("%H:%M", time.localtime(epoch))'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 clock raises on a stamp it cannot read"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_clock_never_raises"
|
||||
old = ''' if epoch is None:
|
||||
return value if isinstance(value, str) else ""'''
|
||||
new = ''' if epoch is None:
|
||||
raise ValueError(value)'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 byline passes an address through"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_byline_hides_addresses"
|
||||
old = ''' return "" if _is_address(bare) else who'''
|
||||
new = ''' return who'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 the date tooltips keep HH:MM"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_date_stamp_is_house_form"
|
||||
old = ''' return time.strftime("%Y-%m-%d %H%M", time.localtime(epoch))'''
|
||||
new = ''' return time.strftime("%Y-%m-%d %H:%M", time.localtime(epoch))'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a pick's answer line shows the raw stamp"
|
||||
file = "booth/templates/_marks.html"
|
||||
test = "tests/test_antislop.py::test_rendered_marks_use_the_house_clock"
|
||||
old = '''{{ a.answer.answered_at|clock }}'''
|
||||
new = '''{{ a.answer.answered_at }}'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a memo line shows the raw stamp"
|
||||
file = "booth/templates/_marks.html"
|
||||
test = "tests/test_antislop.py::test_rendered_marks_use_the_house_clock"
|
||||
old = '''{{ a.created|clock }}'''
|
||||
new = '''{{ a.created }}'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a memo line shows the poster's address"
|
||||
file = "booth/templates/_marks.html"
|
||||
test = "tests/test_antislop.py::test_rendered_marks_use_the_house_clock"
|
||||
old = '''{% if a.by|byline %} · {{ a.by|byline }}{% endif %}'''
|
||||
new = '''{% if a.by %} · {{ a.by }}{% endif %}'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 an answer line shows the answerer's address"
|
||||
file = "booth/templates/_marks.html"
|
||||
test = "tests/test_antislop.py::test_rendered_marks_use_the_house_clock"
|
||||
old = '''{% if a.answer.answered_by|byline %} · {{ a.answer.answered_by|byline }}{% endif %}'''
|
||||
new = '''{% if a.answer.answered_by %} · {{ a.answer.answered_by }}{% endif %}'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 the inline ask's state tag shows the raw stamp"
|
||||
file = "booth/templates/_ask_inline.html"
|
||||
test = "tests/test_antislop.py::test_embed_fragment_uses_the_house_clock"
|
||||
old = '''✓ answered <time datetime="{{ a.answer.answered_at }}">{{ a.answer.answered_at|clock }}</time>'''
|
||||
new = '''✓ answered {{ a.answer.answered_at }}'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a board row shows HH:MM"
|
||||
file = "booth/templates/booth.html"
|
||||
test = "tests/test_antislop.py::test_board_rows_use_the_house_clock"
|
||||
old = '''{{ e.when|clock }}'''
|
||||
new = '''{{ e.when }}'''
|
||||
|
||||
# ---- S1, folded from the heid bug-hunt (thread 01M3MGPFKWBX0SJK5HFE0P3AFM)
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 clock raises OverflowError on an int past float range (Q1)"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_clock_never_raises"
|
||||
old = ''' try:
|
||||
f = float(value)
|
||||
except (OverflowError, ValueError):
|
||||
return None
|
||||
return f if math.isfinite(f) else None'''
|
||||
new = ''' return float(value) if math.isfinite(value) else None'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a date-only stamp prints an invented 0000 (Q8)"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_clock_forms"
|
||||
old = ''' if isinstance(value, str) and ":" not in value:'''
|
||||
new = ''' if False:'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 an address with a port prints (Q7)"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_byline_hides_addresses"
|
||||
old = ''' if s.count(":") == 1:
|
||||
candidates.add(s.split(":", 1)[0])'''
|
||||
new = ''''''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a zero-width character disguises an address (Q7)"
|
||||
file = "booth/app.py"
|
||||
test = "tests/test_antislop.py::test_byline_hides_addresses"
|
||||
old = ''' bare = "".join(ch for ch in who if unicodedata.category(ch) not in ("Cf", "Cc")).strip()'''
|
||||
new = ''' bare = who.strip()'''
|
||||
|
||||
[[mutation]]
|
||||
label = "S1 a board row's author is not bylined (Q5)"
|
||||
file = "booth/templates/booth.html"
|
||||
test = "tests/test_antislop.py::test_board_rows_use_the_house_clock"
|
||||
old = '''{% if e.who|byline %}<span class="board-who">{{ e.who|byline }}</span>{% endif %}'''
|
||||
new = '''{% if e.who %}<span class="board-who">{{ e.who }}</span>{% endif %}'''
|
||||
Reference in New Issue
Block a user