From 5f9f2926a82ccc6ad42fac2360c236d0c3032169 Mon Sep 17 00:00:00 2001 From: Ethan Miller Date: Fri, 22 May 2026 00:56:35 -0400 Subject: [PATCH] Add prepaid compute credit breakage guard --- .../README.md | 24 ++ .../acceptance-notes.md | 18 + prepaid-compute-credit-breakage-guard/demo.js | 32 ++ .../index.js | 354 ++++++++++++++++++ .../package.json | 11 + .../reports/demo.mp4 | Bin 0 -> 80307 bytes .../reports/reviewer-packet.md | 26 ++ .../reports/summary.json | 163 ++++++++ .../reports/summary.svg | 45 +++ .../requirements-map.md | 11 + .../sample-data.js | 115 ++++++ prepaid-compute-credit-breakage-guard/test.js | 78 ++++ 12 files changed, 877 insertions(+) create mode 100644 prepaid-compute-credit-breakage-guard/README.md create mode 100644 prepaid-compute-credit-breakage-guard/acceptance-notes.md create mode 100644 prepaid-compute-credit-breakage-guard/demo.js create mode 100644 prepaid-compute-credit-breakage-guard/index.js create mode 100644 prepaid-compute-credit-breakage-guard/package.json create mode 100644 prepaid-compute-credit-breakage-guard/reports/demo.mp4 create mode 100644 prepaid-compute-credit-breakage-guard/reports/reviewer-packet.md create mode 100644 prepaid-compute-credit-breakage-guard/reports/summary.json create mode 100644 prepaid-compute-credit-breakage-guard/reports/summary.svg create mode 100644 prepaid-compute-credit-breakage-guard/requirements-map.md create mode 100644 prepaid-compute-credit-breakage-guard/sample-data.js create mode 100644 prepaid-compute-credit-breakage-guard/test.js diff --git a/prepaid-compute-credit-breakage-guard/README.md b/prepaid-compute-credit-breakage-guard/README.md new file mode 100644 index 00000000..e3d3d699 --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/README.md @@ -0,0 +1,24 @@ +# Prepaid Compute Credit Breakage Guard + +This module is a focused Revenue Infrastructure slice for issue #20. It evaluates prepaid AI compute and top-up credit lots before finance recognizes expired unused balances as breakage revenue. + +The guard keeps protected balances out of revenue, routes open refund obligations to liability review, requires notice and terms evidence before breakage, and emits deterministic audit artifacts for revenue close review. + +## What It Checks + +- Expired credit lots with explicit breakage terms, customer notice evidence, and closed refund windows. +- Expired lots that must stay on finance hold because evidence is missing or a dispute is active. +- Credits approaching expiration that need a customer notice before close. +- Grant-funded or no-expiration credits that must carry forward. +- Refund-window balances that remain liabilities. +- Usable active balances that should not be recognized. + +## Run + +```bash +npm run check +npm test +npm run demo +``` + +Demo artifacts are written under `reports/`, including JSON, Markdown, SVG, and the generated MP4 demo attached in the PR. diff --git a/prepaid-compute-credit-breakage-guard/acceptance-notes.md b/prepaid-compute-credit-breakage-guard/acceptance-notes.md new file mode 100644 index 00000000..a556a697 --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/acceptance-notes.md @@ -0,0 +1,18 @@ +# Acceptance Notes + +This contribution intentionally does not create live payment links, invoices, subscriptions, or provider integrations. It is a self-contained control module that can be reviewed without credentials. + +Acceptance checks: + +- `npm run check` validates all JavaScript files. +- `npm test` covers breakage-ready lots, missing-notice holds, refund liabilities, expiring-soon notices, protected grant credits, active usable credits, and deterministic audit digests. +- `npm run demo` writes reviewer artifacts to `reports/`. +- The PR includes a short demo video generated from the SVG summary. + +Non-overlap: + +- Not a generic billing ledger. +- Not a usage metering/idempotency guard. +- Not payment webhook or payment rail failover logic. +- Not collections, dispute evidence, tax exemption, plan-proration, storage overage, or account-transfer work. +- Focused only on prepaid AI compute credit breakage and expiration controls. diff --git a/prepaid-compute-credit-breakage-guard/demo.js b/prepaid-compute-credit-breakage-guard/demo.js new file mode 100644 index 00000000..8de1451d --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/demo.js @@ -0,0 +1,32 @@ +const fs = require("node:fs"); +const path = require("node:path"); +const { + analyzeCreditBreakage, + renderMarkdownReport, + renderSvgSummary, +} = require("./index"); +const { sampleCreditLots } = require("./sample-data"); + +const reportsDir = path.join(__dirname, "reports"); +fs.mkdirSync(reportsDir, { recursive: true }); + +const result = analyzeCreditBreakage(sampleCreditLots, { + asOf: "2026-05-22T12:00:00.000Z", + expiringSoonDays: 30, +}); + +fs.writeFileSync( + path.join(reportsDir, "summary.json"), + `${JSON.stringify(result, null, 2)}\n` +); +fs.writeFileSync( + path.join(reportsDir, "reviewer-packet.md"), + renderMarkdownReport(result) +); +fs.writeFileSync( + path.join(reportsDir, "summary.svg"), + renderSvgSummary(result) +); + +console.log("prepaid compute credit breakage guard demo artifacts written"); +console.log(`audit digest: ${result.auditDigest}`); diff --git a/prepaid-compute-credit-breakage-guard/index.js b/prepaid-compute-credit-breakage-guard/index.js new file mode 100644 index 00000000..7246f11d --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/index.js @@ -0,0 +1,354 @@ +const crypto = require("node:crypto"); + +const DAY_MS = 24 * 60 * 60 * 1000; + +function parseDate(value, field) { + const date = new Date(value); + if (Number.isNaN(date.getTime())) { + throw new Error(`invalid date for ${field}`); + } + return date; +} + +function remainingCents(lot) { + return Math.max( + 0, + Number(lot.originalCents || 0) - + Number(lot.usedCents || 0) - + Number(lot.refundedCents || 0) + ); +} + +function requireLotFields(lot) { + const required = [ + "id", + "customerName", + "issuedAt", + "expiresAt", + "originalCents", + "usedCents", + "terms", + ]; + + for (const field of required) { + if (lot[field] === undefined || lot[field] === null || lot[field] === "") { + throw new Error(`missing required credit lot field: ${field}`); + } + } +} + +function evaluateLot(lot, options) { + requireLotFields(lot); + + const asOf = parseDate(options.asOf, "asOf"); + const expiresAt = parseDate(lot.expiresAt, `expiresAt for ${lot.id}`); + const balanceCents = remainingCents(lot); + const daysUntilExpiry = Math.ceil((expiresAt.getTime() - asOf.getTime()) / DAY_MS); + const terms = lot.terms || {}; + const reasons = []; + const actions = []; + + const base = { + id: lot.id, + customerName: lot.customerName, + creditType: lot.creditType || "ai_compute_top_up", + issuedAt: lot.issuedAt, + expiresAt: lot.expiresAt, + balanceCents, + daysUntilExpiry, + recognizableBreakageCents: 0, + refundLiabilityCents: 0, + protectedBalanceCents: 0, + reasons, + actions, + }; + + if (balanceCents === 0) { + return { + ...base, + status: "depleted", + reasons: ["credit lot has no remaining balance"], + actions: ["No revenue action required"], + }; + } + + if (terms.grantFunded || terms.noExpiration || terms.expirationProhibited) { + reasons.push( + terms.grantFunded + ? "grant or contract terms prohibit expiration" + : "credit terms do not permit expiration" + ); + actions.push( + "Carry balance forward", + "Exclude from automated breakage recognition", + "Attach grant or customer contract evidence" + ); + return { + ...base, + status: "protected", + protectedBalanceCents: balanceCents, + actions, + }; + } + + if (lot.refundWindowOpen || lot.activeRefundRequest) { + reasons.push( + lot.activeRefundRequest + ? "customer refund request is active" + : "refund window remains open" + ); + actions.push( + "Reserve as refund liability", + "Do not recognize breakage until refund rights close", + "Route to finance review" + ); + return { + ...base, + status: "refund_liability", + refundLiabilityCents: balanceCents, + actions, + }; + } + + if (daysUntilExpiry > options.expiringSoonDays) { + reasons.push("credit lot remains active"); + actions.push( + "Keep credits usable", + "Monitor drawdown before the next close cycle" + ); + return { + ...base, + status: "usable", + actions, + }; + } + + if (daysUntilExpiry >= 0) { + reasons.push("credit lot is approaching expiration"); + actions.push( + "Send expiration notice before recognizing any breakage", + "Keep credits usable through the expiration deadline" + ); + return { + ...base, + status: "notice_due", + actions, + }; + } + + if (!terms.allowsBreakageRecognition) { + reasons.push("terms do not explicitly allow breakage recognition"); + } + + if (!lot.noticeSentAt) { + reasons.push("customer notice evidence is missing"); + } + + if (!lot.refundWindowClosed) { + reasons.push("refund window closure evidence is missing"); + } + + if (lot.activeDispute) { + reasons.push("active dispute prevents revenue close"); + } + + if (reasons.length > 0) { + actions.push( + "Hold balance out of recognized revenue", + "Send final notice or collect missing evidence", + "Route to finance review before close" + ); + return { + ...base, + status: "finance_hold", + actions, + }; + } + + return { + ...base, + status: "breakage_ready", + recognizableBreakageCents: balanceCents, + reasons: [ + "credit expired", + "terms allow breakage recognition", + "notice and refund closure evidence are present", + ], + actions: [ + "Recognize breakage after finance approval", + "Attach customer notice and terms evidence", + "Record audit digest in revenue close packet", + ], + }; +} + +function analyzeCreditBreakage(lots, options = {}) { + if (!Array.isArray(lots)) { + throw new Error("credit lots must be an array"); + } + + const normalizedOptions = { + asOf: parseDate(options.asOf || new Date().toISOString(), "asOf").toISOString(), + expiringSoonDays: Number(options.expiringSoonDays ?? 30), + }; + + const evaluatedLots = lots.map((lot) => evaluateLot(lot, normalizedOptions)); + const totals = evaluatedLots.reduce( + (acc, lot) => { + acc.openBalanceCents += lot.balanceCents; + acc.breakageEligibleCents += lot.recognizableBreakageCents; + acc.refundLiabilityCents += lot.refundLiabilityCents; + acc.protectedBalanceCents += lot.protectedBalanceCents; + + if (lot.status === "notice_due") { + acc.noticeDueCents += lot.balanceCents; + } + if (lot.status === "finance_hold") { + acc.financeHoldCents += lot.balanceCents; + } + if (lot.status === "usable") { + acc.usableBalanceCents += lot.balanceCents; + } + return acc; + }, + { + openBalanceCents: 0, + breakageEligibleCents: 0, + noticeDueCents: 0, + refundLiabilityCents: 0, + financeHoldCents: 0, + protectedBalanceCents: 0, + usableBalanceCents: 0, + } + ); + + const result = { + asOf: normalizedOptions.asOf, + expiringSoonDays: normalizedOptions.expiringSoonDays, + totals, + lots: evaluatedLots, + }; + + return { + ...result, + auditDigest: createAuditDigest(result), + }; +} + +function stableStringify(value) { + if (Array.isArray(value)) { + return `[${value.map(stableStringify).join(",")}]`; + } + + if (value && typeof value === "object") { + return `{${Object.keys(value) + .sort() + .map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`) + .join(",")}}`; + } + + return JSON.stringify(value); +} + +function createAuditDigest(result) { + const payload = { + asOf: result.asOf, + totals: result.totals, + lots: result.lots.map((lot) => ({ + id: lot.id, + status: lot.status, + balanceCents: lot.balanceCents, + recognizableBreakageCents: lot.recognizableBreakageCents, + refundLiabilityCents: lot.refundLiabilityCents, + protectedBalanceCents: lot.protectedBalanceCents, + reasons: lot.reasons, + })), + }; + + return crypto.createHash("sha256").update(stableStringify(payload)).digest("hex"); +} + +function formatDollars(cents) { + return `$${(cents / 100).toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`; +} + +function renderMarkdownReport(result) { + const rows = result.lots + .map( + (lot) => + `| ${lot.id} | ${lot.status} | ${formatDollars(lot.balanceCents)} | ${formatDollars( + lot.recognizableBreakageCents + )} | ${lot.actions[0]} |` + ) + .join("\n"); + + return `# Prepaid Compute Credit Breakage Review + +As of: ${result.asOf} +Audit digest: ${result.auditDigest} + +## Revenue Close Totals + +- Open balance: ${formatDollars(result.totals.openBalanceCents)} +- Breakage eligible: ${formatDollars(result.totals.breakageEligibleCents)} +- Notice due: ${formatDollars(result.totals.noticeDueCents)} +- Refund liability: ${formatDollars(result.totals.refundLiabilityCents)} +- Finance hold: ${formatDollars(result.totals.financeHoldCents)} +- Protected balance: ${formatDollars(result.totals.protectedBalanceCents)} +- Currently usable: ${formatDollars(result.totals.usableBalanceCents)} + +## Lot Decisions + +| Lot | Status | Balance | Recognizable | First action | +| --- | --- | ---: | ---: | --- | +${rows} +`; +} + +function renderSvgSummary(result) { + const statusColors = { + breakage_ready: "#15803d", + notice_due: "#d97706", + refund_liability: "#b91c1c", + finance_hold: "#7c3aed", + protected: "#0369a1", + usable: "#4b5563", + depleted: "#9ca3af", + }; + + const bars = result.lots + .map((lot, index) => { + const width = Math.max(32, Math.round((lot.balanceCents / result.totals.openBalanceCents) * 780)); + const y = 230 + index * 58; + const color = statusColors[lot.status] || "#4b5563"; + return ` + ${lot.id} + + ${lot.status} ${formatDollars(lot.balanceCents)} +`; + }) + .join("\n"); + + return ` + + Prepaid Compute Credit Breakage Guard + Revenue close review for AI compute top-up credits + + + Open ${formatDollars(result.totals.openBalanceCents)} | Breakage ${formatDollars(result.totals.breakageEligibleCents)} | Holds ${formatDollars(result.totals.financeHoldCents)} | Refunds ${formatDollars(result.totals.refundLiabilityCents)} + ${bars} + Audit digest: ${result.auditDigest} + + +`; +} + +module.exports = { + analyzeCreditBreakage, + createAuditDigest, + renderMarkdownReport, + renderSvgSummary, +}; diff --git a/prepaid-compute-credit-breakage-guard/package.json b/prepaid-compute-credit-breakage-guard/package.json new file mode 100644 index 00000000..5a62a47b --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/package.json @@ -0,0 +1,11 @@ +{ + "name": "prepaid-compute-credit-breakage-guard", + "version": "1.0.0", + "private": true, + "type": "commonjs", + "scripts": { + "check": "node --check index.js && node --check sample-data.js && node --check demo.js && node --check test.js", + "test": "node test.js", + "demo": "node demo.js" + } +} diff --git a/prepaid-compute-credit-breakage-guard/reports/demo.mp4 b/prepaid-compute-credit-breakage-guard/reports/demo.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..6071f73fa7b6160c8392516b22d2ee8416268813 GIT binary patch literal 80307 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
  • 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 OOioR} + + Prepaid Compute Credit Breakage Guard + Revenue close review for AI compute top-up credits + + + Open $7,900.00 | Breakage $1,250.00 | Holds $2,450.00 | Refunds $500.00 + + lot-expired-eligible + + breakage_ready $1,250.00 + + + lot-expired-no-notice + + finance_hold $950.00 + + + lot-refund-window-open + + refund_liability $500.00 + + + lot-expiring-soon + + notice_due $1,800.00 + + + lot-grant-no-expiry + + protected $1,100.00 + + + lot-active-future + + usable $800.00 + + + lot-dispute-hold + + finance_hold $1,500.00 + + Audit digest: efffbafb34aec9e909ee2113672b18b88840ae580c37ef37207a2c7c8308a015 + + diff --git a/prepaid-compute-credit-breakage-guard/requirements-map.md b/prepaid-compute-credit-breakage-guard/requirements-map.md new file mode 100644 index 00000000..9b1f7071 --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/requirements-map.md @@ -0,0 +1,11 @@ +# Requirements Map + +Issue #20 describes Revenue Infrastructure for subscription billing, AI compute billing, top-ups, institutional invoices, and licensing revenue. This slice focuses on the AI compute billing/top-up close process. + +| Issue requirement | Implementation coverage | +| --- | --- | +| AI compute billing and top-ups | Models prepaid AI compute credit lots, usage drawdown, expiration, and breakage review. | +| Transparent quotas and usage meters | Keeps active usable balances separate from expired breakage candidates. | +| Billing engine controls | Requires explicit terms, customer notices, refund-window closure, and dispute checks before recognizing breakage. | +| Audit-ready revenue operations | Emits deterministic JSON, Markdown, SVG, and audit digest artifacts for finance review. | +| Safe payment/revenue handling | Uses synthetic data only and performs no live payment, Stripe, PayPal, bank, or credential operations. | diff --git a/prepaid-compute-credit-breakage-guard/sample-data.js b/prepaid-compute-credit-breakage-guard/sample-data.js new file mode 100644 index 00000000..4cf24a7a --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/sample-data.js @@ -0,0 +1,115 @@ +const sampleCreditLots = [ + { + id: "lot-expired-eligible", + customerName: "North Valley Lab", + creditType: "ai_compute_top_up", + issuedAt: "2025-11-15T00:00:00.000Z", + expiresAt: "2026-04-15T00:00:00.000Z", + originalCents: 250000, + usedCents: 125000, + refundedCents: 0, + noticeSentAt: "2026-03-01T10:00:00.000Z", + refundWindowClosed: true, + terms: { + allowsBreakageRecognition: true, + }, + }, + { + id: "lot-expired-no-notice", + customerName: "Bioinformatics Core", + creditType: "ai_compute_top_up", + issuedAt: "2025-10-01T00:00:00.000Z", + expiresAt: "2026-04-20T00:00:00.000Z", + originalCents: 120000, + usedCents: 25000, + refundedCents: 0, + noticeSentAt: null, + refundWindowClosed: true, + terms: { + allowsBreakageRecognition: true, + }, + }, + { + id: "lot-refund-window-open", + customerName: "Quantum Methods Group", + creditType: "ai_compute_top_up", + issuedAt: "2026-01-10T00:00:00.000Z", + expiresAt: "2026-04-01T00:00:00.000Z", + originalCents: 75000, + usedCents: 25000, + refundedCents: 0, + noticeSentAt: "2026-03-10T10:00:00.000Z", + refundWindowOpen: true, + refundWindowClosed: false, + terms: { + allowsBreakageRecognition: true, + }, + }, + { + id: "lot-expiring-soon", + customerName: "Genomics Pilot Program", + creditType: "ai_compute_top_up", + issuedAt: "2026-02-01T00:00:00.000Z", + expiresAt: "2026-06-02T00:00:00.000Z", + originalCents: 240000, + usedCents: 60000, + refundedCents: 0, + noticeSentAt: null, + refundWindowClosed: false, + terms: { + allowsBreakageRecognition: true, + }, + }, + { + id: "lot-grant-no-expiry", + customerName: "NIH Shared Instrumentation Award", + creditType: "grant_compute_credit", + issuedAt: "2025-12-01T00:00:00.000Z", + expiresAt: "2026-05-01T00:00:00.000Z", + originalCents: 200000, + usedCents: 90000, + refundedCents: 0, + noticeSentAt: null, + refundWindowClosed: false, + terms: { + grantFunded: true, + noExpiration: true, + allowsBreakageRecognition: false, + }, + }, + { + id: "lot-active-future", + customerName: "Climate Modeling Center", + creditType: "ai_compute_top_up", + issuedAt: "2026-05-01T00:00:00.000Z", + expiresAt: "2026-08-30T00:00:00.000Z", + originalCents: 125000, + usedCents: 45000, + refundedCents: 0, + noticeSentAt: null, + refundWindowClosed: false, + terms: { + allowsBreakageRecognition: true, + }, + }, + { + id: "lot-dispute-hold", + customerName: "Materials Discovery Consortium", + creditType: "ai_compute_top_up", + issuedAt: "2025-09-15T00:00:00.000Z", + expiresAt: "2026-04-10T00:00:00.000Z", + originalCents: 190000, + usedCents: 40000, + refundedCents: 0, + noticeSentAt: "2026-03-01T10:00:00.000Z", + refundWindowClosed: true, + activeDispute: true, + terms: { + allowsBreakageRecognition: true, + }, + }, +]; + +module.exports = { + sampleCreditLots, +}; diff --git a/prepaid-compute-credit-breakage-guard/test.js b/prepaid-compute-credit-breakage-guard/test.js new file mode 100644 index 00000000..fe06c849 --- /dev/null +++ b/prepaid-compute-credit-breakage-guard/test.js @@ -0,0 +1,78 @@ +const assert = require("node:assert/strict"); +const { + analyzeCreditBreakage, + createAuditDigest, +} = require("./index"); +const { sampleCreditLots } = require("./sample-data"); + +const AS_OF = "2026-05-22T12:00:00.000Z"; + +function byId(result, id) { + const lot = result.lots.find((entry) => entry.id === id); + assert.ok(lot, `expected lot ${id} to exist`); + return lot; +} + +function run() { + const result = analyzeCreditBreakage(sampleCreditLots, { + asOf: AS_OF, + expiringSoonDays: 30, + }); + + assert.equal(result.asOf, AS_OF); + assert.equal(result.totals.openBalanceCents, 790000); + assert.equal(result.totals.usableBalanceCents, 80000); + assert.equal(result.totals.breakageEligibleCents, 125000); + assert.equal(result.totals.noticeDueCents, 180000); + assert.equal(result.totals.refundLiabilityCents, 50000); + assert.equal(result.totals.financeHoldCents, 245000); + assert.equal(result.totals.protectedBalanceCents, 110000); + + const eligible = byId(result, "lot-expired-eligible"); + assert.equal(eligible.status, "breakage_ready"); + assert.equal(eligible.recognizableBreakageCents, 125000); + assert.deepEqual(eligible.actions, [ + "Recognize breakage after finance approval", + "Attach customer notice and terms evidence", + "Record audit digest in revenue close packet", + ]); + + const noNotice = byId(result, "lot-expired-no-notice"); + assert.equal(noNotice.status, "finance_hold"); + assert.equal(noNotice.recognizableBreakageCents, 0); + assert.ok(noNotice.reasons.includes("customer notice evidence is missing")); + + const refund = byId(result, "lot-refund-window-open"); + assert.equal(refund.status, "refund_liability"); + assert.equal(refund.refundLiabilityCents, 50000); + assert.equal(refund.recognizableBreakageCents, 0); + + const expiring = byId(result, "lot-expiring-soon"); + assert.equal(expiring.status, "notice_due"); + assert.equal(expiring.daysUntilExpiry, 11); + assert.deepEqual(expiring.actions, [ + "Send expiration notice before recognizing any breakage", + "Keep credits usable through the expiration deadline", + ]); + + const grant = byId(result, "lot-grant-no-expiry"); + assert.equal(grant.status, "protected"); + assert.equal(grant.protectedBalanceCents, 110000); + assert.ok(grant.reasons.includes("grant or contract terms prohibit expiration")); + + const future = byId(result, "lot-active-future"); + assert.equal(future.status, "usable"); + assert.equal(future.recognizableBreakageCents, 0); + + const digest = createAuditDigest(result); + assert.match(digest, /^[a-f0-9]{64}$/); + assert.equal(digest, createAuditDigest(result)); + + assert.throws( + () => analyzeCreditBreakage([{ id: "bad", originalCents: 1 }], { asOf: AS_OF }), + /missing required credit lot field/ + ); +} + +run(); +console.log("prepaid compute credit breakage guard tests passed");