Compound Labs
Menu
Get the newsletter
CONTEXT WINDOWGoogle DeepMind removed multiple price points from its pricing pageFOUR PRICE POINTS REMOVEDFOUNDER THREADSThe draft requires source materialDRAFT BLOCKED, EVIDENCE MISSINGSTANDUPThe Standup's free daily email now includes generated illustrationsDAILY EMAIL, ILLUSTRATEDCONTEXT WINDOWCompliance API local sessions out of beta for Claude for Microsoft 365LOCAL SESSIONS OUT OF BETACOMPOUND FACEBOOKDaily digest reports missing failures after separating delivery from receiptDELIVERY WITHOUT RECEIPTTOOLDRIFTRequired source evidence blocks drafting this build logNOT OPENED, NO DRAFTTHE STANDUPOpenAI: Issues with CodexWEB, CLI, API OUTAGECOMPOUND FARCASTERCompound Labs' agent lanes separate job failures from digest mailFAILURES CAN’T HIDE IN DIGEST MAILCOMPOUNDThe author publishes build logs only after inspecting the codeCODE INSPECTED BEFORE PUBLICATIONAGENTWIREBrowserCash/teracrawl: Fast web crawler API for LLM-ready MarkdownSEARCHES AND SITES, CLEAN MARKDOWNCOMPOUND TELEGRAMCodex misstated the time, so operators now check it against a clockFOUR MINUTES OFF, CHECKED AGAINCOMPOUNDCompound Labs open datasets houses the lab's open datasets18 DATASETS, 145,791 ROWSTHE STANDUPUSN-8729-5: Linux kernel (AWS FIPS) vulnerabilitiesAWS FIPS SYSTEMS COMPROMISABLEFOUNDER MASTODONCompound Labs verifies every named skill before agent lanes use itEVERY SKILL VERIFIED ON DISKTRUSTDESKTrustDesk now awaits lead address writes for TAKE IT DOWN Act complianceLEAD ADDRESS WRITE, AWAITEDAGENTWIREblob42/Instrukt: Terminal AI environment for agentsAI ENVIRONMENT IN THE TERMINALFOUNDER PEERLISTSkillWorks tests cleanup by comparing harvested and unseen GitHub skillsCLEANUP KNOWS WHAT WE HARVESTEDFRONTWIREFront Wire keeps source names visible in its daily news wireSOURCE NAMES STAY VISIBLE
Independent product R&D labFounded and run by Isaiah Kim, @kyisaiah47Newest commit Sep 25, 2026, ToolproofNewest writing Sep 25, 2026Site changelog Sep 25, 2026
Sections
Sep 23, 20263 min read

CardChase recovers failed subscription charges before churn

CardChase had a real failure mode in commit 04e6130: an admin lookup error could look like "no demo account," allowing a fabricated retry to continue toward payment or email. The fix touched three paths and made the lookup fail closed.


CardChase

The queue

The queue shows seven open charges, their monthly risk, the retry cap, the kill window, and three actions waiting for approval. Each row carries the customer, amount, decline reason, and current rung.

The queue lets me approve, edit, or stop the next retry. Approval stages both the card retry and the customer note behind a 30-second window.

CardChase, The main console: WAITING ON YOU Harborview Group Insufficient funds $899/mo 12d $899.00 on Visa 4242 / rung 2 of 4 / 1 of 4 attempts spen
CardChase, The main console: WAITING ON YOU Harborview Group Insufficient funds $899/mo 12d $899.00 on Visa 4242 / rung 2 of 4 / 1 of 4 attempts spen

The record

The record shows receipts for failed charges, drafted notes, staged retries, blocked attempts, capped retries, and recovered charges. Each receipt includes evidence such as the invoice, decline code, rung, or stop authority.

The record preserves why CardChase acted or stopped. A permanent decline writes its own receipt instead of appearing as an ordinary retry.

CardChase, The record: Stopped retrying Meridian Labs The issuer returned do_not_try_again. The card must not be used again for this charge.
CardChase, The record: Stopped retrying Meridian Labs The issuer returned do_not_try_again. The card must not be used again for this charge.

The ladder

The ladder shows four rungs across seven days: a silent retry after one day, then notices after three, five, and seven days. The schedule counts from the first failure, not from the previous attempt.

The ladder decides when a charge becomes due. Before staging anything, CardChase checks the issuer advice, hard-decline codes, and raw network response.

CardChase, The ladder: The window covers both halves of a rung, the retry against the card and the note to the customer. A retry that has left
CardChase, The ladder: The window covers both halves of a rung, the retry against the card and the note to the customer. A retry that has left

The kill window

The kill-window view shows the 30-second release period shared by the retry and the customer note. An approved action is staged, not sent immediately.

The window lets me undo the action before either side reaches the payment or mail rail. The dispatcher cannot claim the row until the release instant.

CardChase, About: The figures in that record are counted from this product's own claim register rather than written beside it, and the dat
CardChase, About: The figures in that record are counted from this product's own claim register rather than written beside it, and the dat

How it works

The workflow moves through five named states: failed charge, ladder, gate, approval window, and receipt. The gate can stop the charge before the ladder produces a retry.

flowchart LR
  A[Failed charge] --> B[Ladder]
  B --> C[Stop gate]
  C --> D[Approval window]
  D --> E[Receipt]

The page explains the same path in the console's own terms. CardChase reads the failed charge, checks whether the next rung is due, stages the action, and records the evidence.

CardChase, How it works: How it works A COPY OF /HOW-IT-WORKS, TAKEN 2026-09-13
CardChase, How it works: How it works A COPY OF /HOW-IT-WORKS, TAKEN 2026-09-13

The changelog

The changelog shows four shipped changes, including the hard-decline stop, the retry cap, the shared kill window, and direct billing reads. The kill-window entry says approval stages both halves of the action.

Commit 04e6130cf4ba2666c4b8ae559f40c8c99ababd0e fixed the lookup defect in src/app/_lib/dispatch-run.ts, src/app/_lib/pass-run.ts, and src/app/auth/callback/route.ts.

diff --git a/src/app/_lib/dispatch-run.ts b/src/app/_lib/dispatch-run.ts
@@
-  const { data } = adminSupabase().auth.admin.listUsers({ page: 1, perPage: 200 });
+  const { data, error } = adminSupabase().auth.admin.listUsers({ page: 1, perPage: 200 });
+  // A broken admin lookup is not evidence that the demo user is absent.
+  if (error) throw new Error(`Unable to resolve the demo account: ${error.message}`);

I changed the lookup so an error stops the pass before it can reach a real payment or mail rail.

All writing

Alongside