Every rule in our published operating system carries the failure that taught it to us. This is the part no vendor volunteers. One curation rule, same as the scoreboard: entries that name our clients or client-confidential figures are held back from this public log, because the privacy we promise you is the privacy we practice. What is shown is unedited.
L183 · Aug 11, 2026 · failure_patterns · Claude
Two Stripe facts to hold. (1) ATTACHED IS NOT DEFAULT: `setup_future_usage: 'off_session'` attaches a payment method to the customer but does NOT set `invoice_settings.default_payment_method`, and Stripe auto-selects only from the default. Off-session charges must name `payment_method` explicitly. (2) NEVER list payment methods with `type: 'card'` when checking whether a customer can be charged. Checkout saves Link payment methods as type `link`; a card-only list returns zero for customers who have paid repeatedly. Query with no type filter. More generally: when a fix ships with "not verified end-to-end against the live provider", treat the unverified segment as still broken and schedule the verification, because the next bug report will come from a customer.
What goes wrong otherwise: Auto-recharge charged nobody for weeks after the trigger was fixed: an off-session PaymentIntent naming only a Stripe `customer` cannot find their saved payment method, and while diagnosing it I nearly concluded the customer had no payment method because I listed with `type: 'card'`.
L182 · Aug 11, 2026 · failure_patterns · Swamp
Treat the "[email] UNTAGGED SEND -- no kind, so no preference can gate it" warning as a blocking finding, never log noise: an untagged send falls into the hidden 'other' bucket, so a person who switched off that exact category still receives it (an active pause is the only thing that stops them). Before sending any broadcast, verify the gate against production by calling filterByPreference with both the untagged and the intended kind and comparing who is blocked and FOR WHAT REASON. Same-answer-different-reason is a latent bug, not a pass. Also: a preference-blocked recipient makes sendEmail return false, which the broadcast script counts as a failure. It is not one, and it must never be retried with --only=.
What goes wrong otherwise: Both weekly senders called sendEmail with no `kind`, so In The Swamp was not governed by the "In the Swamp" switch on the preference page. Caught at the issue #32 gate, one issue after we announced that switch as a feature.
L181 · Aug 11, 2026 · operational_heuristics · Claude
Read the no-operating system-recipients rule at its actual scope. It governs cold blasts, list sends, and the weekly Swamp digest. It does not govern 1:1 correspondence with a person David met in person and already has a live relationship with. Before excluding a named individual on a rule, check whether the rule is about list mechanics or about the person.
What goes wrong otherwise: Applied the permanent no-operating system-recipients rule as a blanket block and excluded Rabbi Mendel Shemtov from a rabbi outreach list because his address is mendel.shemtov@eosworldwide.com. David corrected this: Shemtov is one of the three.
L180 · Aug 11, 2026 · operational_heuristics · Swamp
Sales-invite prospects (/admin/join-link) are added to the Swamp subscriber list at mint, so they already receive the weekly. Before building any new outreach channel to a group, check whether an existing channel already reaches them and carry the message there. The weekly now renders a per-recipient unclaimed-credit block (src/shared/swamp-claim.ts): one block per person, silent once redeemed, silent for anyone who already has an OTP account because redemption is stamped at ORG CREATION and an existing org clicking the link would get nothing.
What goes wrong otherwise: SUCCESS: Swamp -- the weekly email already reached the prospect list that was never told about its credit
L179 · Aug 10, 2026 · operational_heuristics · Dan
When extracting an EJS partial, pass EVERY value it reads explicitly; a template-scope var/function can never be inherited by an include no matter how the include is written. And build render-test fixtures from the route's actual reply.view() call and nothing more -- a fixture richer than the route hides exactly this class of break. Prove a new guard has teeth by reverting the fix under it and watching it fail.
What goes wrong otherwise: Extracted an EJS row into a partial on /l8 and passed only { m: m }. teamLookup and meetingTypeLabel are declared with var/function INSIDE l8-list.ejs, so they live in the compiled template function's scope, not in the data object EJS copies into an include. Every render 500'd with "teamLookup is not defined" and the meetings page was down in production until David reported it. My render test passed because the fixture invented teamLookup and meetingTypeLabel as page locals -- values the route does not pass -- so the test exercised a page that does not exist.
L178 · Aug 10, 2026 · operational_heuristics · Outreach
When Clay and LeadMagic's email-finder both return nothing for a confirmed named human, do not mark the row "needs research". Instead: (1) find the name by web search, (2) validate a junk address at that domain FIRST, (3) if the junk control returns invalid, the validator discriminates on that domain, so test 3-5 real patterns (first@, flast@, first.last@) and any that returns valid is a real mailbox. If the junk control returns unknown or valid, the domain is catch-all and validation proves nothing there, so do NOT guess. This produced 6 of 15 sends in one run, including kika@kikastretchstudios.com and dfink@iflexfranchise.com, which no enrichment tool returned. Corollary: LeadMagic email-finder returned nothing on 4 of 4 attempts and remains unfit for sourcing, but is the right tool for the validation step.
What goes wrong otherwise: SUCCESS: Outreach tripled per-run sends (5 to 15) by treating address VERIFICATION, not name-finding, as the real bottleneck, and by testing address patterns against a per-domain junk control.