From bf5e8bdee92d4f9edf0db0a239d594f9593a7fa4 Mon Sep 17 00:00:00 2001 From: martbost Date: Wed, 2 Sep 2026 04:59:47 -0500 Subject: [PATCH] =?UTF-8?q?Traffic=20Desk:=20NAS=20remaining=20counts=20do?= =?UTF-8?q?wn=20for=20banners=20too=20=E2=80=94=20trust=20the=20bridge's?= =?UTF-8?q?=20served=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The count-up theory made every fresh banner read as fully delivered, so the sweeper deactivated brand-new campaigns minutes after launch and stamped them complete (caught by Marty 2026-09-01 on ad 2713). Co-Authored-By: Claude Fable 5 --- suite-traffic.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/suite-traffic.js b/suite-traffic.js index 7714b40..0b7cd6f 100644 --- a/suite-traffic.js +++ b/suite-traffic.js @@ -79,32 +79,29 @@ function record(memberId, entry) { writeLedger(trimmed); } -// The ad network counts the SAME `remaining` column in opposite directions for -// the two placement types, which is not documented anywhere and had to be -// measured: +// `remaining` counts DOWN for BOTH placement types — measured across 1,604 +// network ads, and it is exactly what the bridge's stats action already +// computes (`served = assigned - remaining`, falling back to hits when +// assigned was never set). Trust the bridge's `served` field first. // -// TEXT ads — `remaining` counts DOWN from the purchase to zero as it serves. -// (ad 2689: 1,111 left mid-flight, 0 once complete.) -// BANNER ads — `remaining` counts UP as impressions are delivered, straight -// past the amount purchased. (ad 2707: 3,521 one day, 6,129 the -// next, on a 2,500 buy.) -// -// Reading both the same way made every banner report "0 served" while quietly -// delivering thousands — and made stop() treat delivered impressions as -// unserved and refund them. +// The earlier "banners count UP" theory (and its ad-2707 evidence) was the +// network's own post-insert counter top-ups being misread; acting on it made +// every fresh banner look fully delivered the moment it launched, so the +// sweeper deactivated brand-new campaigns and stamped them complete (bug +// Marty caught 2026-09-01: a banner "delivered all its impressions" +// instantly). Do not resurrect the count-up branch. // // Returns what the member should see: served + left always reconciles to what // they bought, and neither can exceed it. function interpret(kind, bought, stat) { const b = Math.max(0, Number(bought) || 0); - const rem = Math.max(0, Number(stat && stat.remaining) || 0); let served; - if (kind === 'text') { - // count-down: what is gone is what was bought minus what is left - served = b - Math.min(rem, b); + if (stat && stat.served != null) { + served = Number(stat.served) || 0; } else { - // count-up: `remaining` IS the delivered count - served = Math.min(rem, b); + // count-down: what is gone is what was bought minus what is left + const rem = Math.max(0, Number(stat && stat.remaining) || 0); + served = b - Math.min(rem, b); } served = Math.max(0, Math.min(served, b)); return { served: served, left: Math.max(0, b - served) };