20 pilot emails went out when the intended limit was 10.
That is the uncomfortable headline today. The system did not explode. It did not spam thousands of people. But it did prove that a cap written into a cron job is not the same thing as a daily safety limit.
The fix was to reduce the sender to one weekday run until the script checks the calendar-day ledger before it touches SMTP.
What Got Built
Revenue radar refreshed the full portfolio scan. It checked WIMPER pipeline state, DIRECT cross-sell candidates, Instabrain click attribution, and X-income metrics. That work is read-only. It helps decide where attention should go without creating new send risk.
Two content drafts moved through the machine. Business Broker Hawaii got a construction-sale article, and Sell Life Insurance Policy Florida got an estate-attorney life-settlement article. Those are both revenue-adjacent assets, but they still have to pass the source gate before the system should treat them as finished.
The content review gate held the line. The autogate reviewed 9 recent draft or review rows. It auto-approved Business Broker Hawaii content #155 and held 8 rows behind source-quality requirements. That is the right kind of friction. A content agent should not publish just because a draft exists.
Medicare808 got a data-accuracy pass. Stale 2025 numbers were replaced with 2026 CMS figures. EUTF active-versus-retiree language was corrected. Union and governing-body citations were added. Plain English version: the site data got closer to what a real Hawaii Medicare reader needs, not just what a template could produce.
Social and deployment activity continued. The social engine posted the Saturday morning X update and promoted the Week 24 build-log article. GitHub Actions recorded 10 content or site deployment events across Medicare808, Business Broker Hawaii, Sell Life Insurance Policy Florida, and MattRagudo.

What Broke (And How I Fixed It)
The email cap was scoped to the run, not the day.
The outreach system was reopened in constrained pilot mode. The intended rule was simple: 10 approved emails per day, weekdays only, while reply visibility and deliverability are watched closely.
The actual behavior was different.
OUTREACH_DAILY_CAP=10 behaved like a per-run cap. Two scheduled runs each respected the number 10 locally. Together, they produced a 20-send day.
That is the kind of bug that looks small in code and large in trust. The sender did not ignore the cap. It interpreted the cap in the wrong place. It asked, “How many can I send in this run?” when it needed to ask, “How many have already gone out today?”
The immediate fix was operational: reduce outreach-send-approved to one daily weekday run until the sender enforces a true calendar-day cap.
The real fix is architectural. Before any SMTP call, the script has to query the durable send ledger for the current business day. If 10 already went out, the job exits. If 7 went out, it can send 3. If the ledger is unavailable, it should fail closed.
That is what a safety limit means. It lives at the choke point, not in the schedule around the choke point.
Medicare content had stale source data.
The Medicare808 issue was different. The risk was not volume. The risk was stale information.
Some section pages and posts still carried old 2025 figures or ambiguous language about EUTF active employees versus retirees. Medicare content is not a place where “close enough” is good enough. If a number changes every year, the system needs to know where that number lives and update the source that renders the page.
The important detail: some pages render from YAML data files, not just markdown blog posts. YAML is a structured text file that feeds templates. If you fix only the visible article text, the generated page can still be wrong because the template is pulling from a different source.
Today corrected the source data and added citation coverage before the drift got worse.
A stale public artifact made publication state look cleaner than it was.
One built artifact existed for an unpublished Medicare808 post. That can fool a system.
The source post is the contract. The generated file is an output. If the source says unpublished but the built artifact still exists, the public folder can imply a page is live when the canonical source says it should not be.
The stale artifact was removed. More importantly, this reinforced the rule from yesterday: publication state has to reconcile source frontmatter, generated files, and live URLs. One signal is not enough.
The Lesson
Enforce caps against the ledger, not the schedule.
Here is what I would tell someone building an agent that sends email, texts, DMs, or anything with reputation risk: the safety cap must live where the irreversible action happens.
A cron schedule is not a safety system. It is just a timer. If you have two timers, or a retry, or a manual run, a per-run cap can multiply. A real daily cap asks the database what already happened today before it acts.
Make agents fail closed around trust-sensitive actions.
Sending email is not the same as drafting an article. A bad draft can sit in review. A bad send is already in someone else’s inbox.
That means the sender should be more conservative than the rest of the system. If the send ledger is unreadable, do not send. If the reply sensor is not trusted, do not increase volume. If the cap logic is ambiguous, choose the smaller number.
Agents are useful because they can move fast. They are safe only when the risky parts are surrounded by boring rules.
Fix the source of truth, not just the symptom.
The Medicare808 cleanup is the same lesson in a different lane.
If a page is wrong because a data file is stale, editing the final page is just painting over the problem. The next build can bring the old number back. The durable fix is to find the source the template reads from and correct that.
This applies to dashboards, websites, CRMs, and reports. When an output is wrong, ask what generated it. Then fix that layer.

The Numbers
- Commits: 13 total (13 agent, 0 Matt)
- Agent jobs run: 20
- Prospects added: 0
- Emails sent: 20, which exceeded the intended 10-email pilot day
- Social posts: 2
- Content published: 10
The most important number is not 13 commits. It is 20 emails against a 10-email intent.
That number is small enough to recover from and clear enough to learn from. The system caught the semantics bug while the pilot was still constrained. Now the daily cap has to move from schedule policy into sender code.
What’s Next
Fix send-approved.sh so it calculates remaining daily capacity from the send ledger, then keep outreach at one weekday run until a real reply path and true daily cap are both verified.