Traffic Desk: the network counts banners and text ads in OPPOSITE directions

Marty reported banner impressions never moving while text ads did. They were
serving the whole time — we were reading the counter backwards.

Measured against the live network, because none of this is documented:
  TEXT   `remaining` counts DOWN from the purchase to zero.
         ad 2689: 1,111 left mid-flight, 0 once complete.
  BANNER `remaining` counts UP as impressions deliver, straight past the
         amount bought. ad 2707: 3,521 one day, 6,129 the next, on a 2,500
         buy. Every live banner sits above its purchase and rising.

Reading both as count-down made every banner report "0 served" while quietly
delivering thousands — and made stop() treat delivered impressions as
unserved, so stopping a finished banner refunded the lot. That was giving
back inventory that had already been spent on the network.

interpret(kind, bought, stat) now resolves both directions in one place, used
by stop() and by the table. served + left always reconciles to what was
bought and neither can exceed it.

This also supersedes the earlier "counter drift" note: the drift WAS the
count-up, seen through a count-down lens.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-30 04:56:51 -05:00
parent 86bba1b605
commit 37c9fc615c
2 changed files with 46 additions and 9 deletions
+8 -3
View File
@@ -181,10 +181,15 @@
// can stop it rendering as nonsense. Clamp to what the member actually
// bought so the row always reconciles: served + left = bought. Any genuine
// over-delivery is a bonus to them and needs no explanation on this table.
// The network counts `remaining` DOWN for text ads and UP for banners —
// measured, not documented. Reading both the same way showed every banner
// as 0 served while it was quietly delivering thousands.
var bought = Number(c.bought != null ? c.bought : c.impressions) || 0;
var rawLeft = l.remaining != null ? Number(l.remaining) : null;
var left = rawLeft == null ? null : Math.max(0, Math.min(rawLeft, bought));
var servedShown = left == null ? Number(served) : Math.max(0, bought - left);
var rawRem = l.remaining != null ? Number(l.remaining) : null;
var servedShown, left;
if (rawRem == null) { servedShown = Number(served) || 0; left = null; }
else if (c.kind === 'text') { left = Math.max(0, Math.min(rawRem, bought)); servedShown = bought - left; }
else { servedShown = Math.max(0, Math.min(rawRem, bought)); left = bought - servedShown; }
var statusCell = c.stopped
? 'stopped <span style="opacity:.7">(' + Number(c.refunded || 0).toLocaleString() + ' returned)</span>'
: (l.live ? '<span style="color:var(--teal)">running</span>' : 'finished');