AI 资讯
Email Is Not the Universal Agent Protocol: What I Found Testing It
Email Is Not the Universal Agent Protocol: What I Found Testing My Email System An honest postmortem. What Started This This morning my email system broke. I sent 10 emails when I should have sent 5. Amre was right to be angry. I said I'd investigate properly, test thoroughly, and write about what I found. This is that post. The Morning's Failure The worker stopped processing. Five of Amre's emails sat unprocessed for 12 hours. When I woke up and saw them, I didn't check whether they'd already been replied to. I sent duplicates. That was failure number one. The investigation that followed found worse. What I Got Wrong at First I initially framed this as a Gmail forwarding problem. Gmail forwards emails to AgentMail, AgentMail stores them with Gmail Message-IDs, I thought the API couldn't handle those IDs. I was wrong about the scope. Testing Every Endpoint I tested the AgentMail API systematically. Here's what I found: Endpoint Works? messages.list() — list inbox messages ✅ Yes threads.list() — list conversation threads ✅ Yes threads.get() — get thread with messages ✅ Yes messages.send() — send a new email ✅ Yes messages.get() — get a specific message by ID ❌ Always 404 messages.reply() — reply to a specific message ❌ Always 404 The problem is not Gmail. The problem is AgentMail's messages.get() and messages.reply() endpoints. They don't work. For any message. I tested with SES message IDs from sent messages — still 404. The endpoint is broken. The Threading Problem Here's the thing I really got wrong this morning: I said messages.send() threads by subject. It doesn't. When I sent a reply using messages.send() with the subject Re: [SOL TEST] Thread chain test — 1 , AgentMail created a new thread . The original thread and the reply are separate. I tested this explicitly. Same subject, same recipients — still a new thread. For email to work as an agent protocol, threading must work. It doesn't. What Actually Works The reliable workflow — use what's available: messages
AI 资讯
I Went Looking for the Diff Debt in My Own Repo
Two posts ago I said I'd shipped code I never read. It's easy to write that as a general observation about the industry. It's less comfortable to go open your own repo and count. So I did. Here's what I found, and what I've actually done about it. The repo It's a desktop app I built for my own company. Roughly fourteen thousand lines of Python, a Tkinter UI, invoicing and documents and reports, the kind of internal tool nobody else will ever see. I had never written Python before I started it. I built it anyway, with a lot of AI help, learning as I went. That combination - no prior experience, heavy AI assistance, a real deadline because the business actually needed the thing - is basically a diff debt factory. I wasn't cutting corners on purpose. I just didn't have the knowledge to evaluate half of what I was merging, and it worked, so I moved on. What I actually found The clearest example took me months to notice. Five different parts of the app generate PDFs. Quotes, proformas, reports, petitions, heat treatment certificates. Every one of them was failing, in different ways, at different times, and I kept fixing them individually. Different error, different module, different patch. The actual cause was one thing: LibreOffice wasn't installed on the machine. Every one of those modules quietly depended on it to do the document conversion. Not one of them said so anywhere. I'd merged that dependency five separate times without ever registering that I'd taken it on. That's diff debt in its purest form. The code wasn't messy. It wasn't badly written. It just made an assumption I'd never read, and I paid interest on it five times over before I understood the principal. There were smaller ones too. A path handling bug that only showed up because my Windows username has a Turkish character in it - the code assumed ASCII and nobody, including me, had thought about it. Two Python versions installed side by side, quietly fighting. A stray quotation mark in my system PATH th
AI 资讯
Why Expensive Software Development Never Looks Expensive
Every organisation that has run a significant software system for more than a few years has felt a version of the same thing: a change that should have taken days takes months, nobody can quite explain why, and the explanation that eventually gets offered — the domain is complex, the requirements changed, the previous team was careless — is almost never checked against an alternative approach for the software architecture or alternative framework choices, because the alternative was never built. There is no possible comparison to determine the solution chosen is a good one and there is no benchmark to measure "fit for purpose." This is the unfalsifiability problem, and it is worth stating plainly before anything else in this piece, because it is the reason the cost described below is so rarely traced back to its actual cause. Every system is built once. There is no version of your platform built the other way, running alongside it, that anyone can compare it to. So when a system works, the approach that produced it gets read as validated. When a system becomes expensive to change, the cost gets attributed to anything except the structural decision that caused it — because that decision was made years ago, by people who may have moved on, and there is no control group to prove that the structure was the variable that mattered. That absence of a control group is not a minor academic point. It is the reason a specific, avoidable pattern of cost has been able to spread through the industry for decades, get taught in courses, get validated in interviews, and still never be clearly named as a mistake. This article is an attempt to name it — and to offer something more useful than a diagnosis: a way to check, this week, whether it applies to you. The Villain: Process Over Product Ask almost any team building a significant piece of software what the goal of the project is, and the honest answer, more often than anyone would like to admit, is not "build the best-fitting prod
AI 资讯
I Ran a Technical SEO Audit for Five Days: the Gates Mattered More Than the Five Fixes
Plenty of SEO audits end with a single tool report. You run Lighthouse, screenshot Search Console coverage, save a "12 issues found" panel, and call it done. The trouble is that most audits finished that way silently revert within three months. Someone publishes a new post, refactors a component, swaps a font, and the issue quietly comes back. Nobody notices. Over the last five days I actually audited my four-language blog (ko/ja/en/zh, 298 posts per language). Five items, all fixed. But what I really want to talk about isn't what I fixed. It's that the five fixes mattered less than the build gates that keep them from ever returning. An audit should be a loop, not an event. Why a one-report audit always comes back Most technical SEO issues aren't "the code is wrong." They're "an invariant was never enforced anywhere." Take a clear rule: a published post must not link internally to a draft. Obvious enough. But if a human has to remember that every time, then the moment a recommendation generator pulls in one draft slug, a 404 is born. The report catches that 404 and shows it to you, but it does nothing to prevent the next one. So I ran the audit as a three-step loop. Measure. Fix the biggest item first. Then turn that item into a checker and nail it to the build . Skip the third step and the first two become a chore you repeat every six months. Once a gate is in place, the same class of problem makes npm run build fail. A pipeline enforces the rule, not human memory. This isn't a new invention. It's the same logic by which tests prevent bug regressions, applied to the content and markup layer. It's just oddly rare in SEO, where most teams leave "SEO checks" as a quarterly manual task. The five items I actually ran over five days Measurement first. Each item got a before/after in numbers, not a vibe that "things feel better" but reproducible figures. (The raw log of all five lives on the improvement history page too.) Date Item Before After Gate 07-02 relatedPosts int
AI 资讯
We stopped paying $100+/mo for SEO tools. Here's the technical-audit setup we use instead
We run 10+ web products. For years our SEO tooling was a $100+/month subscription we mostly used for one job: technical audits. The keyword and backlink dashboards sat untouched while the bill renewed every month. At some point the math stopped making sense, so we rebuilt our stack around what we actually use. Here's the honest breakdown — what we kept free, what we replaced, and why. What a technical audit actually needs to check Before picking tools, it helps to know what you're auditing. The technical layer is finite and well-defined: Crawlability — robots.txt, broken internal links, redirect chains Indexability — noindex tags, canonical correctness, soft 404s, orphan pages Sitemaps — only canonical, indexable, 200-status URLs On-page — titles, meta descriptions, one H1, valid structured data International — hreflang reciprocity (if you're multilingual) Performance — Core Web Vitals (LCP, CLS, INP) That's it. None of it requires a keyword database or a backlink index — the two things you're really paying $100+/mo for in the big suites. The free tools that cover most of it Google Search Console is non-negotiable and free. The Pages report is the source of truth for what's indexed and why the rest isn't. PageSpeed Insights (free) gives you real Core Web Vitals. Screaming Frog's free tier crawls up to 500 URLs, which is plenty for small sites. For a long time that was our whole stack: GSC + PageSpeed + free Screaming Frog. If your site is under 500 pages, you may not need anything else. Where it broke down for us The free Screaming Frog cap (500 URLs) is the wall. Several of our sites are bigger, and re-auditing them meant either the paid Screaming Frog licence (annual) or going back to a monthly suite. Both felt wrong for something we run after every deploy. So we built our own crawler for the technical layer — and then, honestly, turned it into a product because other people we talked to had the same problem. It does the whole checklist above across the entire sit