Skip to main content

max / shop

shop-vt: close the last four survivors of the confirming run The re-run came back 170 mutants, 162 caught, 4 missed. Three were tests that looked complete and were not, and each failure mode is worth keeping: - `b - b'0'` and `b / b'0'` agree on '0' and '1'. Every DCS test used a parameter starting with 1, and the first digit is the only one `dcs_entry` ever sees -- so the arithmetic there was tested with the two inputs that cannot distinguish it. - DcsIgnore tested with `ESC \` alone cannot show that it ends on ESC and nothing else: a handler ending on EVERY byte reaches Escape one byte early, and Escape's own ESC arm absorbs the ESC that follows, so the log is identical. A final byte with no terminator separates them. - `buffered_bytes` was asserted over an open OSC, which leaves the parameter list empty -- and `+ 0` and `- 0` are the same sum. Asserted over an open DCS instead, where every term is live. The fourth is excluded: `apc_start`'s clears are always no-ops, because both routes out of ApcString call `apc_end`, which does strictly more. `osc_start` is not excluded and is caught, since it also pushes the first parameter placeholder.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01DwpiantpUgohzML4xr6KeQ
Author: Max Johnson <me@maxj.phd> · 2026-08-31 15:44 UTC
Signed with PGP, not checked
Commit: 8bd3f0ecc4da0555f6d01bb1bf51e90c685bc165
Parent: 1cfcfb2
2 files changed, +48 insertions, -2 deletions
@@ -77,4 +77,18 @@
77 77 # deleting the arm leaves the byte to a `_ => {}` that also holds the state
78 78 # still. Kept because the DEC table names the transition.
79 79 "delete match arm 0x1B in Parser::escape$",
80 +
81 + # --- A reset that its partner has always already done -----------------
82 + #
83 + # `apc_start` clears `apc_buf` and `string_overflow` on the way into an APC,
84 + # SOS or PM body. Every route out of `ApcString` -- the BEL arm and the ESC
85 + # arm, which are the only two -- calls `apc_end`, which clears both and
86 + # shrinks the buffer besides. So the parser is never in Escape about to open
87 + # a string while holding a previous one's bytes or its overflow flag, and
88 + # the opening clear has nothing to clear. Kept because the pairing is what
89 + # makes that true, and a third exit added later would need it.
90 + #
91 + # `osc_start` is NOT here and is caught: it also pushes the first parameter
92 + # placeholder, which is work nothing else does.
93 + "replace Parser::apc_start with \\(\\)",
80 94 ]
@@ -1268,8 +1268,12 @@
1268 1268 fn buffered_bytes_sums_every_buffer_the_parser_holds() {
1269 1269 let mut p = Parser::new();
1270 1270 let mut r = Rec::default();
1271 - // An open OSC with fields, so all four terms are non-zero.
1272 - p.advance(&mut r, b"\x1b]52;c;aGVsbG8=");
1271 + // An open DCS with parameters. The two body buffers are allocated at
1272 + // their resting size from `Parser::new`, so the parameter list is the
1273 + // only term that can be zero -- and an OSC leaves it zero, which lets
1274 + // the `+ params.footprint()` term become `-` unnoticed.
1275 + p.advance(&mut r, b"\x1bP1;2;3");
1276 + assert!(p.params.footprint() > 0, "the parameter term must be live");
1273 1277
1274 1278 let expected = p.osc_buf.capacity()
1275 1279 + p.apc_buf.capacity()
@@ -1547,6 +1551,34 @@
1547 1551 }
1548 1552 }
1549 1553
1554 + /// The digit arithmetic in `dcs_entry` specifically. `b - b'0'` and
1555 + /// `b / b'0'` agree on '0' and '1' and part company at '2', so a test whose
1556 + /// only DCS parameter starts with 1 cannot see the difference -- and the
1557 + /// first digit of a DCS is the one `dcs_entry` handles, every later one
1558 + /// belongs to `dcs_param`.
1559 + #[test]
1560 + fn the_first_dcs_digit_is_a_value_and_not_a_quotient() {
1561 + assert_eq!(
1562 + run(b"\x1bP2q\x1b\\")[0],
1563 + "hook(params=[[2]], intermediates=[], ignore=false, action='q')"
1564 + );
1565 + assert_eq!(
1566 + run(b"\x1bP9q\x1b\\")[0],
1567 + "hook(params=[[9]], intermediates=[], ignore=false, action='q')"
1568 + );
1569 + }
1570 +
1571 + /// DcsIgnore ends on ESC and on nothing else. Testing that with `ESC \` alone
1572 + /// cannot show it: a handler that ends on EVERY byte reaches Escape one byte
1573 + /// early, and the ESC that follows is then absorbed by Escape's own ESC arm,
1574 + /// so the log comes out identical. A final byte with no terminator is what
1575 + /// separates them -- 'B' dispatches from Escape and is silence from
1576 + /// DcsIgnore.
1577 + #[test]
1578 + fn an_abandoned_dcs_swallows_everything_that_is_not_the_terminator() {
1579 + assert_eq!(run(b"\x1bP:qB"), Vec::<String>::new());
1580 + }
1581 +
1550 1582 /// DcsIgnore ends on ESC and nothing else, and the parser comes back out of
1551 1583 /// it. A DcsIgnore that never ends swallows the rest of the stream; one
1552 1584 /// that ends on every byte ends in the middle of the discarded prelude.