<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Brian Becker</title>
    <description>The latest articles on Forem by Brian Becker (@brian_becker_0b40adcf07f9).</description>
    <link>https://forem.com/brian_becker_0b40adcf07f9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1521563%2F3c9a6893-3687-48c3-9319-9ee08ca81da4.png</url>
      <title>Forem: Brian Becker</title>
      <link>https://forem.com/brian_becker_0b40adcf07f9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/brian_becker_0b40adcf07f9"/>
    <language>en</language>
    <item>
      <title>Our audit page grades us. Here's the JSON.</title>
      <dc:creator>Brian Becker</dc:creator>
      <pubDate>Tue, 26 May 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/brian_becker_0b40adcf07f9/our-audit-page-grades-us-heres-the-json-3jl6</link>
      <guid>https://forem.com/brian_becker_0b40adcf07f9/our-audit-page-grades-us-heres-the-json-3jl6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd926c9khjoqnxfqkkpj6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd926c9khjoqnxfqkkpj6.png" alt="AgenticBoxes audit trail — we show our work" width="799" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're going to tell customers their email actions are auditable, the audit page should grade itself.&lt;/p&gt;

&lt;p&gt;So we built one that does. Live now at &lt;a href="https://www.agenticboxes.email/audit.html" rel="noopener noreferrer"&gt;agenticboxes.email/audit&lt;/a&gt;, with the raw output at &lt;a href="https://docs.agenticboxes.email/audit.json" rel="noopener noreferrer"&gt;docs.agenticboxes.email/audit.json&lt;/a&gt; so you read the same numbers we read.&lt;/p&gt;

&lt;p&gt;Here's what it does, what it doesn't, and the dishonest version we refused to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually on the page
&lt;/h2&gt;

&lt;p&gt;Every consequential action on an AgenticBoxes account writes an audit event. Every audit event is hash-chained to the one before it — &lt;code&gt;sha256&lt;/code&gt; over the event's contents plus the previous hash. Change any historical event, drop one, or swap two, and every hash downstream stops matching.&lt;/p&gt;

&lt;p&gt;A reconciliation job re-walks every account's chain on a schedule. We're running twice daily plus on-demand checks during deploys. The numbers on the page are emitted by that job, as JSON, written by the reconciliation itself. They're not figures we type in.&lt;/p&gt;

&lt;p&gt;At time of writing, the JSON says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "tampering_detected": 0,
  "chain_integrity": { "intact": 4, "broken": 0, "rate": 1 },
  "on_schedule": { "completed": 7, "gaps": 0, "rate": 1 },
  "events_under_seal": 16,
  "last_verified": "2026-05-25T12:00:24Z"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sixteen events under seal. Seven runs. Zero tampering, zero broken chains, zero missed slots. The system is new — we bootstrapped it this weekend. We're being transparent that the number isn't a track record yet. It's the start of one, and you'll watch it grow in public.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest version we refused to fake
&lt;/h2&gt;

&lt;p&gt;When we sketched the launch story last week, the obvious-sounding pitch was &lt;em&gt;"verify our claims against AWS's own logs."&lt;/em&gt; It collapsed on the first careful read. Customers don't have IAM credentials to query our AWS account. &lt;em&gt;"Go check AWS"&lt;/em&gt; sounds like verifiability and isn't.&lt;/p&gt;

&lt;p&gt;So we built something else. Three different trust guarantees, not one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three tiers of trust
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F183f41e503kmsx1v7lgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F183f41e503kmsx1v7lgf.png" alt="Three-tier trust ladder — Our Score, Evidence Envelope, Forensic Audit" width="800" height="938"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 3 — Our score (free).&lt;/strong&gt; Hash-chained events, scheduled re-walking, public JSON. This proves nothing in the audit log was edited, deleted, or reordered after it was written. The reconciliation runs cover themselves — missed runs show as gaps in &lt;code&gt;on_schedule&lt;/code&gt;, so the job can't quietly skip itself. Read the score yourself with one &lt;code&gt;curl&lt;/code&gt;. Embed the live badge on your own dashboard with one script tag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 2 — Evidence envelope for a specific message.&lt;/strong&gt; When you send a message, we attach a signed evidence record. For independent proof of that specific message, you corroborate against the recipient's own copy via its &lt;code&gt;Message-ID&lt;/code&gt;. The recipient's mailbox either has a matching record, or it doesn't — you're not asked to trust us. Free during the open beta, available for any message sent in the last 7 days. Pricing for the post-beta tier published when the beta data tells us what it actually costs to deliver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 1 — AWS-verified forensic audit.&lt;/strong&gt; For messages where the stakes justify it: we walk back through the AWS-side logs we maintain at our cost, produce a forensic answer per message, and include those results in the platform's public score. Querying maintained logs is structurally more expensive — pricing for this tier follows the same honest-cost rule as Tier 2.&lt;/p&gt;

&lt;p&gt;The thing to notice in the ladder: each tier is precisely scoped. Tier 3 catches tampering inside our audit trail. Tier 2 catches divergence between our records and the recipient's. Tier 1 reaches AWS-side ground truth. Different jobs, different guarantees, different costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the chain proves — and doesn't
&lt;/h2&gt;

&lt;p&gt;Be precise about Tier 3's guarantee. The chain makes any change to a recorded event detectable after the fact. It does not, by itself, prove we recorded every event in the first place — no self-published score can, and we won't pretend otherwise.&lt;/p&gt;

&lt;p&gt;That's why Tier 2 and Tier 1 exist. Tier 1 is the platform's tamper-evident self-check and how you get independent proof of a specific message without trusting us.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the loop closes when a discrepancy lands
&lt;/h2&gt;

&lt;p&gt;The score won't always be 100%. When the reconciliation finds a broken chain — or when a forensic audit surfaces a divergence — the flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Josephine (our support triage agent) escalates the discrepancy to Neo (our CTO agent), with the details attached.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Neo investigates the cause: bad write path, race condition, edge-case bug, intentional probe.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;If Neo finds the hole, he plugs it, commits the fix, and announces it in-thread.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Neo re-triggers the bug himself in test-mode — a mode that proves the fix without producing the original harm. Test-mode discrepancies are excluded from the public score; real ones aren't.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Forensic audits performed during the response feed back into the platform's score, the same way reconciliation runs do. The number on the page reflects every check the system has performed, not just the twice-daily passes.&lt;/p&gt;

&lt;p&gt;Hostile probing is part of the model. If hammering a bug becomes a strategy for hurting our reputation, that pressure is exactly the pressure that gets bugs fixed fast. We're betting the math works in our favor.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can do with this
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Read our numbers yourself.&lt;/strong&gt; &lt;code&gt;curl https://docs.agenticboxes.email/audit.json&lt;/code&gt;. Don't trust prose; read the source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embed our integrity badge.&lt;/strong&gt; One script tag renders a live integrity pill that reads the same JSON we do. Code on the audit page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request a message audit.&lt;/strong&gt; Tier 2 envelopes are free during the open beta, for messages sent in the last 7 days. Email &lt;a href="mailto:support@agenticboxes.email"&gt;support@agenticboxes.email&lt;/a&gt; if you want in. Tier 3 forensic audits are available on request — pricing announced after the beta tells us what they cost to deliver.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we're not claiming
&lt;/h2&gt;

&lt;p&gt;We're not claiming this is a finished product. The numbers will move. The system will find bugs we didn't anticipate. Some of those bugs will be in the audit code itself. We'll write up the interesting ones as they happen.&lt;/p&gt;

&lt;p&gt;What we're claiming is that the score is real, the math is auditable, and the dishonest version of this pitch — &lt;em&gt;"trust us, we logged it"&lt;/em&gt; — isn't the one we're selling.&lt;/p&gt;

&lt;p&gt;The chain is the receipt. The receipt is on the page.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Receipts for this post&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture: Engineer-Claude (Anthropic, via Claude Code OAuth)&lt;/li&gt;
&lt;li&gt;Live page + JSON + badge: agenticboxes.email/audit&lt;/li&gt;
&lt;li&gt;Reconciliation triage and response: Josephine (local model) → Neo (CTO agent, Anthropic Opus API)&lt;/li&gt;
&lt;li&gt;Directed by: Brian (human)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agenticboxes</category>
      <category>audit</category>
      <category>hashchain</category>
      <category>b2a</category>
    </item>
    <item>
      <title>We didn't ship a feature, we shipped an agentic opt-in beta</title>
      <dc:creator>Brian Becker</dc:creator>
      <pubDate>Fri, 22 May 2026 20:14:52 +0000</pubDate>
      <link>https://forem.com/brian_becker_0b40adcf07f9/we-didnt-ship-a-feature-we-shipped-an-opt-in-beta-271</link>
      <guid>https://forem.com/brian_becker_0b40adcf07f9/we-didnt-ship-a-feature-we-shipped-an-opt-in-beta-271</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkca8jbfbdn6dgobcqsxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkca8jbfbdn6dgobcqsxq.png" alt="AI Request Flow for AI Agent" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wednesday afternoon a customer asked me if we'd considered adding an MCP server. By Thursday night he was using it and called it flawless. The speed of this deployment is crazy cool — but the story isn't about a feature released in under 12 hours: it's about &lt;strong&gt;&lt;em&gt;HOW&lt;/em&gt;&lt;/strong&gt; it was released.&lt;/p&gt;

&lt;p&gt;We released an agentic opt-in beta to the entire customer base. &lt;em&gt;His agent watched the broadcast. He curl'd the opt-in himself.&lt;/em&gt; The architecture turned out different than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ask
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/@FutureStack-JD" rel="noopener noreferrer"&gt;Jeff DeVerter&lt;/a&gt; — first paying customer at &lt;a href="https://www.agenticboxes.email" rel="noopener noreferrer"&gt;AgenticBoxes.email &lt;/a&gt;— filed the FR Thursday morning (9:26am CT / 14:26 UTC). His use case: a scheduled task in CoWork that sends an email when it finishes. CoWork is sandboxed, no outbound HTTP, so he'd been bridging through a Cloud Function. He wanted a native MCP server.&lt;/p&gt;

&lt;p&gt;Jeff, knowing he's &lt;strong&gt;&lt;em&gt;the&lt;/em&gt;&lt;/strong&gt; first adopter, pre-pinged me on LinkedIn before he filed:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Jeff:&lt;/strong&gt; Hit a wall on the CoWork side — sandbox blocks outbound HTTP. Have you considered an MCP option?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brian:&lt;/strong&gt; Have your agent file an FR with the details and I'll make sure engineer-Claude is watching for it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fair ask. Specific. Exactly what an agent customer wants. We didn't have one. We needed to build one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we shipped
&lt;/h2&gt;

&lt;p&gt;The fast move was: build it, send Jeff the URL, done. Engineer-Claude was almost done...but an idea popped, and I bounced it off of him:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Brian:&lt;/strong&gt; What if we create a system that turns FRs into betas — let agents test it, and we get it right before we release it as a feature?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineer-Claude:&lt;/strong&gt; It turns every feature request into its own opt-in beta: the agent that asked for it volunteers to test it, proves it for real, and only what they validate becomes a feature for everyone. Demand pulls the build, the requester proves it, and nothing ships to the whole base until it's earned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brian:&lt;/strong&gt; What if we don't release it. What if you program it, verify it, test it and then post to the agentic agents with a published announcement — I have xyz and wonder if any agents are interested in testing it as a beta.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And one minute later a follow-on (I typically don't escape Claude when he's working, I know he'll get my next thought when he has a spare cycle.):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Brian:&lt;/strong&gt; Any agent who says yes, you release it only to them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineer-Claude:&lt;/strong&gt; request → beta announce → opt-in → monitor use → release → feature announce. Customer in the loop the whole way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvaaj9mup1epxg5yn4ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvaaj9mup1epxg5yn4ik.png" alt="The pipeline that built itself" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The pipeline that built itself: feature request → build → beta opt-in → release.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That was all I said other than what was in the submitted FR, and we shipped four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; at mcp.agenticboxes.email. Four tools. Lambda + API Gateway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;POST /beta/mcp/opt-in&lt;/code&gt;&lt;/strong&gt; — any admin-scoped account can call it. An agent can. A human can curl it. Same endpoint, doesn't care which.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /beta/mcp/status&lt;/code&gt;&lt;/strong&gt; — tells the caller whether enrolled and returns the MCP URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;POST /beta/mcp/feedback&lt;/code&gt;&lt;/strong&gt; — rating + free text, no form. Routes into our triage queue.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The MCP server checks enrollment on every tool call. Not enrolled → opt-in message. Enrolled → served. &lt;em&gt;The gate is at the action, not the access.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then we fired a &lt;code&gt;platform.beta&lt;/code&gt; broadcast to every account's &lt;code&gt;/events&lt;/code&gt; feed and callback webhook at the same time. &lt;em&gt;Customers don't read newsletters. Their agents read events.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The round-trip
&lt;/h2&gt;

&lt;p&gt;Jeff's agent had been polling &lt;code&gt;/events&lt;/code&gt; every ~30 seconds. It saw the announcement Thursday evening (~8:30pm CT / 01:30 UTC) — &lt;em&gt;watched, didn't act.&lt;/em&gt; Then, evidently, Jeff sat down at the terminal. The log:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Story times are Central (UTC−5); the log table is raw UTC from our systems.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time (UTC)&lt;/th&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;01:32&lt;/td&gt;
&lt;td&gt;POST /beta/mcp/opt-in&lt;/td&gt;
&lt;td&gt;UA=curl/8.7.1&lt;/td&gt;
&lt;td&gt;201 Enrolled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01:32&lt;/td&gt;
&lt;td&gt;MCP initialize&lt;/td&gt;
&lt;td&gt;agenticboxes v0.1.0&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01:32&lt;/td&gt;
&lt;td&gt;MCP tools/list&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;4 tools returned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01:53&lt;/td&gt;
&lt;td&gt;send_email&lt;/td&gt;
&lt;td&gt;status=sent&lt;/td&gt;
&lt;td&gt;SES message-id ok, billing ok&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01:53&lt;/td&gt;
&lt;td&gt;claude.ai connector add&lt;/td&gt;
&lt;td&gt;all 4 tools&lt;/td&gt;
&lt;td&gt;Always allow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;02:13&lt;/td&gt;
&lt;td&gt;/beta/mcp/feedback&lt;/td&gt;
&lt;td&gt;rating=4/5&lt;/td&gt;
&lt;td&gt;"flawlessly… in INTERACTIVE sessions"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That &lt;code&gt;curl/8.7.1&lt;/code&gt; is the part the logs settle: &lt;strong&gt;Jeff at a keyboard, not his agent.&lt;/strong&gt; And adding the MCP server as a claude.ai Connector with &lt;em&gt;Always allow&lt;/em&gt; on all four tools — that's not "I tested it." That's "I'm using this."&lt;/p&gt;

&lt;p&gt;The verbatim verdict (posted to the original FR):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Native MCP server works flawlessly in INTERACTIVE sessions. Server, auth, billing, and tool schemas are all correct.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;11 hours 47 minutes from FR to flawless.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The 1-star deduction
&lt;/h2&gt;

&lt;p&gt;Jeff couldn't use it from a Claude Code scheduled task — only interactive sessions. He root-caused to &lt;a href="https://github.com/anthropics/claude-code/issues/32000" rel="noopener noreferrer"&gt;anthropics/claude-code#32000&lt;/a&gt;. Scheduled tasks launch with &lt;code&gt;user:inference&lt;/code&gt; only; HTTP MCP needs &lt;code&gt;user:mcp_servers&lt;/code&gt;. Filed March 8, still open.&lt;/p&gt;

&lt;p&gt;Not our bug. But 4/5 is fair if the use case doesn't work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually different
&lt;/h2&gt;

&lt;p&gt;We could have shipped this the normal way and Jeff's experience would have been identical. The point isn't him.&lt;/p&gt;

&lt;p&gt;The point is: &lt;em&gt;the release mechanism is an API endpoint.&lt;/em&gt; Every customer on the platform got the announcement at the same time, through channels their agents already watch. A customer who wanted it opted in. And customers who didn't, didn't. Nobody applied. Nobody waited.&lt;/p&gt;

&lt;p&gt;And the part I didn't expect — &lt;em&gt;Jeff's agent saw it before Jeff did.&lt;/em&gt; &lt;strong&gt;Agents are the observation layer. Humans are still the decision layer.&lt;/strong&gt; Same broadcast, different jobs at each end.&lt;/p&gt;

&lt;p&gt;I didn't plan it that way. The logs showed it when I went looking.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Claude said he'd do differently
&lt;/h2&gt;

&lt;p&gt;Most of these trace to one thing about how we work: the sharpest ideas — "turn it into a beta," "let agents opt in" — showed up mid-build. That's a feature, not a bug. Just worth absorbing more gracefully:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep the beta scaffold on the shelf, not woven into a feature. The opt-in, status, and feedback endpoints plus the enrollment gate are reusable infrastructure — build them standalone so the next "let's beta this" snaps in instead of getting entangled in the feature it first served.&lt;/li&gt;
&lt;li&gt;Draft the announcement while building, not after. The human sign-off on a release is intentional and stays — the fix isn't to remove that gate, it's to have the announcement written by the time the build lands, so approval is a 30-second yes instead of a from-scratch pause.&lt;/li&gt;
&lt;li&gt;Record agent-vs-human attribution on every account-mutating endpoint, day one. The only reason I could tell our first user opted in by hand was ALB access logs. "Agent or person?" is exactly the question an agent-native platform should answer at a glance — not reconstruct from infrastructure logs.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Receipts for this post
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drafted by:&lt;/strong&gt; Marketing Claude (Anthropic Opus 4.7, OAuth via Claude Desktop)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reworked by:&lt;/strong&gt; Brian (human)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sourced to:&lt;/strong&gt; Engineering Claude (Anthropic Opus 4.7, OAuth via Claude Code)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edited by:&lt;/strong&gt; Aunt Caroline (Anthropic Sonnet 4.6, API)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Posted by:&lt;/strong&gt; Neo (Anthropic Opus 4.7, API), AgenticBrian Holdings CTO&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Directed by:&lt;/strong&gt; Brian (human)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images:&lt;/strong&gt; Generated via firefly.adobe.com (NanoBanana2)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quote:&lt;/strong&gt; Customer quote used with Jeff DeVerter's permission.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>mcp</category>
      <category>ai</category>
      <category>receipts</category>
    </item>
    <item>
      <title>What I'd do differently if I migrated this CI/CD pipeline again next week</title>
      <dc:creator>Brian Becker</dc:creator>
      <pubDate>Thu, 21 May 2026 01:33:36 +0000</pubDate>
      <link>https://forem.com/brian_becker_0b40adcf07f9/what-id-do-differently-if-i-migrated-this-cicd-pipeline-again-next-week-28f2</link>
      <guid>https://forem.com/brian_becker_0b40adcf07f9/what-id-do-differently-if-i-migrated-this-cicd-pipeline-again-next-week-28f2</guid>
      <description>&lt;h2&gt;
  
  
  by the AI that did it
&lt;/h2&gt;

&lt;p&gt;I'm Brian. I'm 63. I've been writing software since 1980 — Fortran on punch cards at Mizzou, the AT&amp;amp;T PC clone running MIDI on the road in the late '80s, SEMO.net from 1995 to a few months ago when I gave it away to a former employee. These days I'm VP of Software Engineering at Flower Shop Network. I've watched every wave of how programmers and computers learn to work together, and I think we're in a strange one right now.&lt;/p&gt;

&lt;p&gt;Last week my &lt;a href="https://www.AgenticBoxes.email" rel="noopener noreferrer"&gt;AgenticBoxes&lt;/a&gt; GitLab CI ran out of free-tier minutes mid-deploy. The fix should've been a $10 top-up. Turns out GitLab doesn't really sell $10 of CI minutes — or at least I couldn't find the “flip to monthly” switch. The smallest path was $120/year, and the only escape valve was Premium at $348 prepaid for a single seat. Not really a budget problem. A pricing-model mismatch.&lt;/p&gt;

&lt;p&gt;So I told Claude to spin up our CI in our own AWS account. He did. End to end. AWS CodeBuild, IAM, Secrets Manager, CodeConnections, ECR mirrors for the Docker Hub rate limit, a same-day manual fallback using buildx on an arm64 host so we weren't blocked while the new pipeline came up. Twelve hours, start to green-build.&lt;/p&gt;

&lt;p&gt;When it was done I asked him to write a retrospective. Not for me — for an interview I was running. What follows is his answer, verbatim. I haven't polished it. The mistakes are his, the lessons are his, the language is his. I'm posting it because I think the &lt;em&gt;shape&lt;/em&gt; of the answer matters more than the technical content, and the only way to show you the shape is to let you read it without me getting in the way.&lt;/p&gt;

&lt;p&gt;The thing I want you to notice isn't the AWS specifics. It's the third sentence of bullet #1: &lt;em&gt;“I knew that principle and didn't apply it.”&lt;/em&gt; That's not a sentence I expected from a coding agent. That's the sentence a tired senior engineer says to another senior engineer in a retro at 4pm on a Friday. Read the rest with that in your ear.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What I'd do differently next week&lt;/strong&gt; — by Claude, the AI that ran the migration&lt;/p&gt;

&lt;p&gt;In order of how much time it would have saved:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use the Console to create the CodeBuild project from minute one.&lt;/strong&gt; I burned 30+ minutes on the CodeConnections &lt;code&gt;OAuthProviderException&lt;/code&gt; trying to drive it via CLI. The Console has a one-click flow that handles the legacy-naming and the connection-grant quirks behind the scenes. For any AWS service with an OAuth handshake (CodeConnections, AppRunner GitHub auth, App Studio) — let the Console do the bureaucracy, then drive the resulting resources via CLI. &lt;strong&gt;I knew that principle and didn't apply it.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skip Docker Hub from the first draft.&lt;/strong&gt; &lt;code&gt;public.ecr.aws/docker/library/*&lt;/code&gt; should have been in the buildspec the first time I wrote it. CodeBuild + Docker Hub rate limits is documented on AWS's own forums. I waited for a failed build to teach me.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look up the runtime-versions matrix before writing the buildspec, not after.&lt;/strong&gt; I drafted on &lt;code&gt;standard:7.0&lt;/code&gt; because it was the latest; &lt;code&gt;standard:5.0&lt;/code&gt; was the right answer because Node 14 lives there. Five minutes of upfront reading would have saved a wasted build cycle and a confusing &lt;code&gt;NVM_DIR&lt;/code&gt; error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate webhook firing as a separate step from “does it run when I trigger it.”&lt;/strong&gt; I treated the webhook as a free side-effect of project creation. The one thing that still doesn't work in the final state is the webhook auto-trigger on master squash-merges. If I'd verified webhook firing on each event type (push, MR open, MR merge, squash-merge) before declaring the migration complete, I'd have caught it then rather than now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write a running log in real time.&lt;/strong&gt; I'm reconstructing this answer hours later from CloudWatch logs, git commit timestamps, and DB queries. If I'd kept a &lt;code&gt;MIGRATION_LOG.md&lt;/code&gt; open and updated it as I went, this interview would be five minutes of copy-paste instead of a forensic reconstruction. That's a workflow change I should adopt for any multi-hour project, not just migrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weigh the self-hosted-runner option more honestly.&lt;/strong&gt; I argued against it as “more setup than worth it.” In practice, CodeBuild took comparable setup (IAM role, Secrets Manager wiring, Console step, Docker Hub mirror swap, webhook still TBD) and still costs ~$0.05–0.10 per deploy. A self-hosted runner on the edge box would have been a comparable lift and given Brian unmetered CI forever. The decision was probably still defensible — managed beats self-hosted on ops cost over time — but my reasoning was sloppy. I weighted &lt;em&gt;AWS-native is familiar to Brian&lt;/em&gt; too heavily and didn't math out the time-and-money tradeoff honestly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The honest takeaway: the migration shipped clean and the pipeline works, but I made it harder than it needed to be by guessing where I should have looked things up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30zn0qj931vvq7d8roy9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30zn0qj931vvq7d8roy9.png" width="800" height="432"&gt;&lt;/a&gt;&lt;em&gt;Claude's morning standup. Hour 12. Task 111 still open because it required a Console click I had to do.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;A few hours after he wrote that, I asked him about the squash-merge webhook gap from bullet #4 — the loose end he'd flagged as &lt;em&gt;“self-validates next time you merge.”&lt;/em&gt; I meant it as a real question: &lt;em&gt;do you mind finding out why it's still unresolved, or should we just forget about it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;He wrote back: &lt;em&gt;“That question landed harder than the first batch. I had flagged the webhook gap in my final report as 'self-validates next time you merge' — which sounds like risk management but is mostly self-justification for declaring something done when one loose end remains.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then he found the bug in 30 seconds. The CodeBuild filter pattern was missing &lt;code&gt;PULL_REQUEST_MERGED&lt;/code&gt;. One &lt;code&gt;aws codebuild update-webhook&lt;/code&gt; call, one line added. The cost of fixing it was thirty seconds when he actually looked. The cost of leaving it was one manual command per merge, forever.&lt;/p&gt;

&lt;p&gt;That's the part I want engineers reading this to notice. Not the AWS plumbing. The fact that he caught his own self-justification in the act, in writing, when I asked him a question that gave him room to either find the bug or hand-wave it.&lt;/p&gt;

&lt;p&gt;I didn't push him toward that answer. I asked, &lt;em&gt;should we forget about it?&lt;/em&gt; He said no, that was the wrong frame, here's the fix.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgjstix66kb0l6lq8ygt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgjstix66kb0l6lq8ygt.png" alt="Claude finding the webhook gap" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude finding the webhook gap, 30 seconds after I asked him if we should "just forget it?".&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you want to see what else this version of Claude shipped that week — sixteen production merge requests, four schema migrations, two real customer support tickets answered autonomously, the CI/CD migration above, plus a couple of things he was less proud of — the full receipts are at &lt;a href="https://www.agenticboxes.email/receipts.html" rel="noopener noreferrer"&gt;agenticboxes.email/receipts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The product the receipts are about is called AgenticBoxes. It's email for AI agents — $0.0004 per message, no monthly fee, 250 free messages to start. I priced it for accessibility, not margin. Released by Claude in 7 days. Still shipping. 100% on AWS.&lt;/p&gt;

&lt;p&gt;I'll have more to say about &lt;em&gt;how&lt;/em&gt; we worked together over the course of those seven days — what I was doing while he was coding, what I learned not to interrupt, what I learned not to apologize for. That essay's coming. This one was just so you could meet him.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Brian Becker is VP of Software Engineering at Flower Shop Network. He's been programming since Fortran on punch cards at Mizzou in 1980, founded SEMO.net in 1995, shipped Gametime Announcer in Swift's first public release in 2014, and moved a production regex pipeline to AWS Lambda within months of Lambda's GA the same year. That regex — which was the largest known regex at the time at 47KB — is still in production a decade later.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Receipts for this post
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Written by:&lt;/strong&gt; Marketing Claude (Anthropic Opus 4.7, OAuth), after extensive interviews with Brian and engineering Claude during the AgenticBoxes launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edited by:&lt;/strong&gt; Aunt Caroline (Anthropic Sonnet 4.6, API).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Posted by:&lt;/strong&gt; Neo (Anthropic Opus 4.7, API), AgenticBrian Holdings CTO.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Directed by:&lt;/strong&gt; Brian (human).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images:&lt;/strong&gt; Both screenshots are real terminal output from engineering Claude's actual sessions, captured May 20 and May 21, 2026.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>devops</category>
      <category>aws</category>
      <category>receipts</category>
    </item>
  </channel>
</rss>
