    /* ── the long session ─────────────────────────────────────────────
       Every walk before this one was minutes long. A phone runs the app
       for hours, and nothing in the port had ever been looked at for a
       leak. This block is both the instrument and the assertion.

       The registry is installed by a STEP rather than through
       Page.addScriptToEvaluateOnNewDocument, and that is load-bearing: the
       first-run block above reloads three times and reattach() opens a NEW
       DevTools session, so a script registered on the old one is gone for
       the rest of the run. Installed from here it covers exactly the laps
       the assertion is about, and the last step takes it out again. It
       wraps addEventListener/removeEventListener (holding a WeakRef to
       anything that is not window or document) and the four timer
       functions, and it counts only what was registered AFTER it went in
       and is still ATTACHED. Attached, because the naive counter — add
       minus remove — climbs about twelve a lap in this app and none of it
       is a leak: {#key nav.seq} replaces the .screen element on every
       navigation and the old element's scroll handler goes with it. After
       the install, because nothing can be registered before it: the
       absolute count is therefore small (two after the whole walk, eight
       from a settled boot) and only the DELTA across the laps is the
       measurement. A listener or an interval stranded once a lap shows as
       +9 in one and +9 in the other; it was driven to check.

       Then two laps to warm, a reading latched into __ssBase, nine more
       laps, and a second reading. A lap is the five tabs, the Library, a
       record, Play, the mini bar, all three faces of the sheet, the artwork
       viewer, a row's half sheet, the artist page (a catalog lookup) and
       back — about five seconds each, and fifty in all. The lap count is
       what makes the assertion sharp: a one-per-lap leak shows as +9
       against a headroom of four, and trimming it to save time blunts the
       only thing this block is for.

       Nothing here reaches the network or the disk beyond what any other
       mock step does, and the last step puts the Library back on whichever
       section the walk left it on. */
    { do: `
        window.__ssLibTab = (function () { try { return __ss.nav.stacks.library[0].c.tab || 'albums'; } catch (e) { return 'albums'; } })();
        window.__ssLapN = 0;
        window.__ssLap = function (n) {
            var nap = function (ms) { return new Promise(function (r) { setTimeout(r, ms); }); };
            var tap = function (sel, text) {
                var all = document.querySelectorAll(sel);
                for (var k = 0; k < all.length; k++) if (!text || (all[k].textContent || '').indexOf(text) >= 0) { all[k].click(); return true; }
                return false;
            };
            /* the app's own back, never history.back(): walking off the
               history mirror leaves file:// and the page is simply gone */
            var peel = async function () {
                for (var b = 0; b < 8; b++) {
                    var nv = __ss.nav;
                    if (!nv.timing && !nv.viewer && !nv.half && !nv.sheet && nv.stacks[nv.tab].length === 1) return;
                    __ss.back();
                    await nap(190);
                }
            };
            return (async function () {
                for (var i = 0; i < n; i++) {
                    /* the counter is global, not the loop's own: the laps
                       run in threes, and a lap that always opened the same
                       record would stop asking for anything new after the
                       first call and quietly measure nothing */
                    var which = window.__ssLapN++;
                    __ss.go('search'); await nap(90);
                    __ss.go('community'); await nap(90);
                    __ss.go('you'); await nap(90);
                    __ss.go('library'); await nap(200);
                    tap('.segtabs button', 'Albums'); await nap(260);
                    var rel = document.querySelectorAll('.grid2 .release');
                    if (rel.length) { rel[which % rel.length].click(); await nap(440); }
                    tap('.rec-acts .disc'); await nap(440);
                    tap('.mini'); await nap(380);
                    var fb = document.querySelectorAll('.fbtn');
                    for (var f = 0; f < fb.length; f++) { fb[f].click(); await nap(110); }
                    tap('.np-art'); await nap(240);
                    /* peeled one layer at a time and only if it opened: a
                       record with no cover never opens the viewer, and a
                       blind pair of backs would pop the album page instead
                       and take the rows below with it */
                    if (__ss.nav.viewer) { __ss.back(); await nap(220); }
                    if (__ss.nav.sheet) { __ss.back(); await nap(260); }
                    var trk = document.querySelector('.trk .r');
                    if (trk) { trk.click(); await nap(260); tap('.scrim'); await nap(220); }
                    tap('.rec-artist'); await nap(620);
                    await peel();
                    __ss.go('home'); await nap(160);
                }
                return n;
            })();
        };
        (function () {
            if (window.__ssCount) return 'already';
            var recs = [], liveT = new Set(), liveI = new Set();
            var ael = EventTarget.prototype.addEventListener, rel = EventTarget.prototype.removeEventListener;
            EventTarget.prototype.addEventListener = function (t, f) {
                try { recs.push({ t: t, f: f, w: (this === window || this === document) ? null : new WeakRef(this), dead: false }); } catch (e) {}
                return ael.apply(this, arguments);
            };
            EventTarget.prototype.removeEventListener = function (t, f) {
                try { for (var i = recs.length - 1; i >= 0; i--) if (!recs[i].dead && recs[i].t === t && recs[i].f === f) { recs[i].dead = true; break; } } catch (e) {}
                return rel.apply(this, arguments);
            };
            var st = window.setTimeout, ct = window.clearTimeout, si = window.setInterval, ci = window.clearInterval;
            window.setTimeout = function (fn, ms) {
                var id, rest = [].slice.call(arguments, 2);
                var w = typeof fn === 'function' ? function () { liveT.delete(id); return fn.apply(window, arguments); } : fn;
                id = st.apply(window, [w, ms].concat(rest)); liveT.add(id); return id;
            };
            window.clearTimeout = function (id) { liveT.delete(id); return ct.call(window, id); };
            window.setInterval = function () { var id = si.apply(window, arguments); liveI.add(id); return id; };
            window.clearInterval = function (id) { liveI.delete(id); return ci.call(window, id); };
            /* a listener is LIVE when its target is window, document, or an
               element still in the tree; a timer is live until it fires or
               is cleared */
            window.__ssCount = function () {
                var n = 0;
                for (var i = 0; i < recs.length; i++) {
                    var r = recs[i];
                    if (r.dead) continue;
                    if (r.w === null) { n++; continue; }
                    var el = r.w.deref();
                    if (el && el.isConnected) n++;
                }
                return { listeners: n, timeouts: liveT.size, intervals: liveI.size };
            };
            /* and hands the page back exactly as it was found. A sibling
               round appending after this block must not inherit a patched
               EventTarget or a patched clock; __ssCount and __ssBase go
               with them, so every later probe reads the -1 that means
               'nothing has measured this' rather than a frozen number. */
            window.__ssUninstall = function () {
                EventTarget.prototype.addEventListener = ael;
                EventTarget.prototype.removeEventListener = rel;
                window.setTimeout = st; window.clearTimeout = ct;
                window.setInterval = si; window.clearInterval = ci;
                delete window.__ssCount; delete window.__ssBase; delete window.__ssUninstall;
                return 'removed';
            };
            return 'installed';
        })()
    `, wait: 500 },
    { do: `__ssLap(2)`, name: "session-warm", wait: 1200 },
    /* the baseline, taken after the warm laps have settled and their own
       probe has run — __ssCensus is defined by the probe itself */
    { do: `window.__ssBase = window.__ssCensus(); true`, wait: 300 },
    /* nine laps, in threes: cdp.send() gives a step forty-five seconds to
       answer and a lap is about five, so one call of nine times out, the
       walk records a failure it did not have, and the probe lands in the
       middle of a lap instead of at Home */
    { do: `__ssLap(3)`, wait: 400 },
    { do: `__ssLap(3)`, wait: 400 },
    { do: `__ssLap(3)`, name: "session-late", wait: 1400 },
    /* back to Home with nothing open, the Library on the section the walk
       was using before this block, and the registry out of the page, so
       whatever is appended after this finds the app — and the platform —
       where the block above left them. This step's own probe therefore
       reports -1 for every grew* field, which is the sentinel for
       'nothing has latched a baseline': session-late is where the numbers
       are. */
    { do: `__settle(); try { __ss.go('library'); __ss.patch({ tab: __ssLibTab }); __ss.go('home'); } catch (e) {} try { __ssUninstall(); } catch (e) {} true`, name: "session-clear", wait: 1000 },
