<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Dustin Boston</title>
    <link>https://dustin.boston</link>
    <description>A software engineer's notebook about modern web development.</description>
    <atom:link href="https://dustin.boston/feed" rel="self" type="application/rss+xml" />
    
    <item>
      <title><![CDATA[Reduce Maintenance Costs with AI in 10 Easy Prompts]]></title>
      <link>https://dustin.boston/blog/reduce-maintenance-costs-with-ai-in-10-easy-prompts</link>
      <guid isPermaLink="true">https://dustin.boston/blog/reduce-maintenance-costs-with-ai-in-10-easy-prompts</guid>
      <pubDate>Tue, 12 May 2026 19:54:00 GMT</pubDate>
      <description><![CDATA[You Need AI That Reduces Maintenance Costs is a great article. You should definitely read it. It doesn't cover how to reduce maintenance costs with AI, though, so I thought I'd take a stab at that....]]></description>
      <content:encoded><![CDATA[<img src="https://sqxeqjww6gt2tk5u.public.blob.vercel-storage.com/posts/1778732594513-prs-w2tfowASUS4fZLndPY2sXfQ43ePPAf.jpg" alt="A list of PRs in GitHub that all help reduce maintenance costs with AI" /><p><a href="https://www.jamesshore.com/v2/blog/2026/you-need-ai-that-reduces-your-maintenance-costs">You Need AI That Reduces Maintenance Costs</a> is a great article. You should definitely read it. It doesn't cover how to reduce maintenance costs with AI, though, so I thought I'd take a stab at that. First let's talk about the non-AI scenario.</p><h2>How to Reduce Maintenance Costs without AI (traditional advice)</h2><p>Before diving into how to reduce maintenance costs with AI, I think it's worth going over the traditional ways we might reduce costs:</p><ol><li><p>Write less code. I'm not trying to be a smartass, I swear. The cheapest code to maintain is code that doesn't exist. Aggressively delete unused features and dead branches. Resist premature generalization - build for the problem you have, not the one you imagine (this one has been huge for me).</p></li><li><p>Favor boring, simple solutions. For example maybe just stick with React, or better yet, use plain HTML. Clever code is expensive code. Use mature, well-understood languages and frameworks; standardize on a small stack so you're not paying a cognitive tax across dozens of tools. This is what I used to do at the web agency I worked for. Then I automated creation of new projects. "Choose Boring Technology" by Dan McKinley is the canonical essay here.</p></li><li><p>Write tons of automated tests. Without a solid test suite, every change becomes risky and slow. Tests are what make refactoring safe, which is what keeps a codebase from rotting. A reasonable target is enough coverage that developers feel comfortable changing things without fear.</p></li><li><p>Refactor infinitely. Technical debt compounds. Small, ongoing cleanups are dramatically cheaper than periodic "rewrite the legacy system" projects. "Leave the code cleaner than you found it," should be the norm. NOTE: If you feel like being chaotic-neutral at work, which I sometimes like to do, start referring to the current system as the "legacy system."</p></li><li><p>Modular architecture with clear boundaries. Loose coupling and high cohesion let you change one part without breaking others. Architecture is a bit of a weak spot for me. AI can help me learn by applying specific architectures and walking me through them.</p></li><li><p>Good documentation. Document the "why," not the "what." Code shows what it does. What's missing is why a decision was made. Inline comments for non-obvious choices, and runbooks for ops scenarios save lots of time when someone unfamiliar (probably future-you) is debugging at 2am.</p></li><li><p>Strong observability. Good logging, metrics, and tracing turn hour-long debugging sessions into ten-minute ones. You only pay the cost once.</p></li><li><p>Invest in developer experience. Fast builds, fast tests, one-command local setup, fast CI. Every minute of friction multiplied by every developer over years adds up to staggering costs.</p></li><li><p>Manage dependencies carefully. Each dependency is a long-term liability. Prefer fewer, more mature ones. Keep them updated incrementally. Falling years behind on a major framework is one of the most common ways maintenance costs explode.</p></li><li><p>Knowledge transfer. Pair programming, code reviews, rotating ownership, and good onboarding docs reduce bus-factor risk. A system only one person understands is one resignation away from a crisis.</p></li></ol><p>For starting a new project, see my <a href="https://dustin.boston/blog/enterprise-project-checklist">Enterprise Project Checklist</a>. For an existing codebase, here are ten ways to reduce maintenance costs with AI.</p><h2>How to Reduce Maintenance Costs with AI</h2><h3>1. Write Less Code</h3><p>Tell AI to delete some stuff. Ask it to find dead code, unused exports, unreachable branches, and duplicated logic that could be combined. That kind of audit used to be too tedious to do regularly. But AI is good at simplifying clever code, pointing out unnecessary abstractions, and spotting similar modules that should be merged. One could go so far as to set explicit "lines deleted" as a metric alongside features shipped, if one wanted to.</p><pre><code>Audit this codebase for code that should be deleted or consolidated. Look for:

1. Dead code - functions, classes, or files that are never called or imported
2. Unused exports - public symbols with no consumers
3. Unreachable branches - conditionals that can never be true given surrounding logic
4. Duplicated logic - multiple places implementing the same thing with minor variations
5. Speculative abstractions - interfaces, factories, or generic wrappers with one
   concrete implementation and no near-term plan for more
6. Over-clever code that would be clearer as straightforward procedural code

For each finding, return: file and line range, category, a one-paragraph reason it's
a candidate for removal, and a confidence level (high/medium/low) with what would
change your mind.

Sort by confidence, highest first. Don't propose changes that require business
context you don't have - flag those as "needs human input" instead.</code></pre><h3>2. Boring Solutions</h3><p>AI can lay out trade-offs between technology choices. Before adopting a new library or pattern, ask it what the maintenance implications are, what the common pitfalls look like, and what you give up by sticking with the boring option.</p><p>It's also useful for translating clever code into boring code. For example, it can turn a dense functional one-liner into the readable, debuggable equivalent. Push back when it suggests a pattern for what could be a function. Its training data over-indexes on enterprise patterns.</p><pre><code>Audit this codebase for clever code that would be clearer as boring code.
Optimize for the person who will debug this at 2am with no context. Look for:

1. Nested ternaries, point-free chains, dense reduce/flatMap stacks, or
   functional one-liners that hide what the code is actually doing
2. Single-letter variable names outside trivial scopes
3. Deep nesting that could be flattened with early returns
4. Anonymous functions doing non-trivial work that should be named
5. Premature abstractions - factories, generic wrappers, or interfaces with
   one concrete implementation and no near-term plan for more
6. Macros, decorators, or metaprogramming where straightforward code would do

For each finding, return: file and line range, category, a one-paragraph
explanation of why a boring version would be clearer, a proposed rewrite,
and a confidence level (high/medium/low) with what would change your mind.

Sort by confidence, highest first. Skip code where the cleverness is earning
its keep - hot paths, library boundaries, places where the plain version
would be substantially longer. Flag those as "intentional - skipping"
rather than dropping them from the report.</code></pre><h3>3. Automated Tests</h3><p>This is probably the biggest way to reduce maintenance costs with AI. AI can generate unit tests for code, propose edge cases humans tend to miss and write tests that lock in current behavior before you refactor. It can also find flaky tests, slow tests, and redundant tests, and convert integration tests into faster unit tests where that makes sense. There is absolutely no reason to have anything less than 100% code coverage. 100% is easy for AI to track. Anyway, going from 20% coverage to even 80% used to be a quarter-long slog. Now you can do it in a week.</p><pre><code>Audit this codebase for test coverage gaps and weak tests. Aim for full
coverage by surfacing what's missing. Look for:

1. Public functions, methods, and exported modules with no tests at all
2. Tested code where only the happy path is covered, missing: null/undefined
   inputs, empty collections, boundary values (0, 1, max), unicode and
   encoding, concurrency, clock and timezone dependencies
3. Source code paths that aren't reached by any test
4. Tests that don't actually assert anything meaningful (no expects, only
   verifying that the code didn't throw)
5. Flaky tests, slow tests, and tests that duplicate what another test
   already covers
6. Integration tests that could be unit tests if a dependency were mocked

For each finding: file and line range (or test file), category, a
one-paragraph reason it matters, and a confidence level.

Sort by impact: untested code central to the system first, edge cases in
critical paths next, redundancy and flake last. For each untested function,
draft a test in the existing framework and style, including a one-line
comment on what it verifies. Flag any behavior you can't test because it
requires external state or context you don't have - don't fake what you
don't know.</code></pre><h3>4. Refactor Infinitely</h3><p>The small refactors engineers used to skip - rename a poorly-named variable across the codebase, extract a duplicated block, split a 2,000-line file - become minutes of work. A weekly audit surfaces dozens in one pass, sorted by impact. "Leave it cleaner than you found it" used to mean 30 seconds at the end of each task. Now you sweep the whole codebase at once.</p><pre><code>Audit this codebase for small refactors worth doing - the kind that used
to get skipped because they weren't worth the context switch. Look for:

1. Poorly-named variables, functions, or types (cryptic abbreviations,
   misleading names, single letters outside trivial scopes)
2. Duplicated code blocks that could be extracted into a function
3. Files over 500 lines that have grown two or more distinct
   responsibilities and should be split
4. Functions over 50 lines doing more than one thing
5. Long parameter lists (5+) that should be objects
6. Conditional ladders that should be lookup tables or polymorphism
7. Magic numbers and string literals that should be named constants

For each finding: file and line range, category, the current state, the
proposed refactor, estimated work (lines touched, files affected), and a
confidence level.

Sort by impact divided by risk - high-leverage, low-risk refactors first.
Don't propose refactors that require business context you don't have; flag
those as "needs human input."</code></pre><h3>5. Modular Architecture</h3><p>AI can analyze a codebase for boundary violations: modules reaching into each other's internals, circular dependencies, leaky abstractions. Combine it with static analysis and get you a dependency graph plus the worst offenders highlighted. Then have it report back with suggestions. This one catches a lot for me.</p><p>For new code, AI can enforce architectural rules in code review. For existing, tangled systems, it's useful to propose where a monolith can be split, and for doing the mechanical work of moving code once you've decided.</p><pre><code>Audit this codebase for boundary violations:

1. Modules importing each other's internals instead of going through a public interface
2. Circular dependencies between modules
3. Layer violations - a lower layer (data, infrastructure) importing from a higher
   layer (business logic, presentation)
4. Leaked abstractions - a module that's supposed to hide a detail but exposes it
   through return types, error messages, or required parameters
5. Modules that have grown two unrelated responsibilities and should be split
6. Two modules with overlapping responsibilities that should merge

For each finding: the modules involved and the specific import or call that's the
violation, why it's a problem concretely (what it couples, what it blocks), a
suggested fix including the rough shape of any new boundary, and a rough estimate
of how much work the fix is.</code></pre><h3>6. Good Documentation</h3><p>AI can draft docs about decisions made from your commit history that might otherwise get buried. It can turn incident postmortems into first-draft runbooks, generate onboarding docs by reading the codebase, and correct docs that have drifted apart from the code.</p><p>The new problem is making sure AI-generated docs (and comments) show the reasoning, not just restating what the code obviously does. Some docs you might want to have are: architecture, auth, data-migrations, database, environment, features, design guide, and a test plan.</p><pre><code>Audit this codebase's documentation. Compare what exists in /docs (or
equivalent) and any README files against what's actually in the code.
Look for:

1. Modules, features, or subsystems with no documentation at all
2. Documentation that describes behavior that no longer exists, or
   contradicts the current code
3. Decisions captured nowhere - non-obvious architectural choices, library
   selections, or design tradeoffs that a new engineer would have to
   reverse-engineer from git blame
4. Setup or operational steps documented partially but missing crucial
   details (env vars, gotchas, recovery procedures)
5. API surface that's documented for some endpoints or functions but not
   others
6. Comments that restate what the code does without explaining why

Useful targets if you find gaps: architecture, auth, data migrations,
database schema, environment setup, features, design guide, test plan.

For each finding: location, category, what's wrong or missing, what
should exist, and a confidence level. For each gap, draft the missing
documentation - capture the "why," not the "what." Cite commit messages,
PR descriptions, or comments when you can find the reasoning. If you
can't, mark it "needs human input" rather than inventing.

Sort by impact: things a new engineer would hit on day one first.</code></pre><h3>7. Strong Observability</h3><p>AI can add logs, instrumentation, and analytics. It's also useful for writing alerts that catch problems without firing constantly, building better dashboards, and summarizing noisy log streams into something actionable. Over time, incidents resolve faster.</p><pre><code>Audit this codebase and propose observability instrumentation. For each suggestion:
- Location (file and line)
- Type: log (with level), metric (counter/gauge/histogram), or tracing span
- Exact name and tags/attributes
- The question this instrumentation helps answer ("Is the payment gateway slow?"
  not "It logs the duration.")

Prioritize:
- Seams between services (network calls, queue publishes, DB queries)
- Decision points where the code chooses between paths
- Error handlers and retry logic
- Anything with a timeout, backoff, or circuit breaker

Don't suggest logging inside tight loops, logging that restates the function name,
or metrics no dashboard would ever look at. If you're unsure something's worth
instrumenting, leave it out.</code></pre><h3>8. Developer Experience</h3><p>AI can audit your build, test, and CI pipelines for slowness and propose specific fixes like parallelization, caching, test splitting. It can write the scripts that make local setup one command. It's good at upgrading dev tooling, writing better error messages in internal tools, and generating IDE configs and pre-commit hooks tailored to your codebase.</p><pre><code>Audit this project for developer experience problems. Look at:

1. Build config (package.json, Makefile, build scripts) - what's slow, redundant,
   or could be cached or parallelized
2. Test config - slow suites, sequential runs that could parallelize, repeated
   setup that could be hoisted
3. CI pipeline - jobs blocking other jobs unnecessarily, repeated work, missing
   caching
4. Local setup - how many commands does a new dev run before they can boot the
   app? How many implicit dependencies (specific Node version, local Postgres,
   env vars to copy)?
5. Error messages in internal tooling - anything that says "Error" with no
   actionable suggestion

For each finding: current state with the offending file/line, a concrete fix,
and estimated time saved per developer per day if you can estimate it. Sort by
impact (time saved × developers affected).</code></pre><h3>9. Dependencies</h3><p>Major version upgrades that used to be quarter-long projects can often be done in days. AI reads the migration guide, applies the breaking changes across the codebase, updates the tests, and asks about anything that needs human judgment.</p><p>It can also audit your codebase for unmaintained dependencies, known vulnerabilities, or things that could be replaced with standard-library equivalents. Run dependency audits regularly.</p><pre><code>Audit every dependency in this project. For each one, assess:

1. Currency - how many major/minor versions behind latest? When was the
   package last released? Is it still actively maintained?
2. Security - any known CVEs? Any transitive dependencies with known issues?
3. Necessity - how much of the dependency does this codebase actually use?
   Could it be replaced with standard-library equivalents or a few lines of
   in-house code?
4. Migration cost - for any major version we're behind on, read the
   migration guide and estimate the breaking-change surface area in our code.
5. Risk concentration - are we depending on multiple packages from a single
   maintainer or org that's a single point of failure?

For each dependency, return: name, current version, latest version, last
release date, maintenance status, CVE summary, usage scope in our code,
upgrade recommendation (upgrade now / upgrade soon / replace / remove /
leave alone), estimated migration effort, and a confidence level.

Sort by risk: unmaintained or vulnerable packages first, then large
version-lag packages with security implications, then everything else.
Don't suppress deprecation warnings to make things look healthier than
they are - if a deprecation will become a breaking change in the next
version, surface it.</code></pre><h3>10. Spread Knowledge</h3><p>AI partially solves bus-factor risk by reading the codebase and producing the docs that should already exist. Anyone can ask "how does payments work in this system?" and get a useful answer, instead of waiting for the one person who built it. It can also generate role-specific onboarding curricula, summarize how features evolved over time, and create searchable indexes of past decisions. (The manual diagnostic lives in <a href="https://dustin.boston/blog/use-git-log-to-learn-about-a-codebase">a few git log commands</a> - same analysis, more typing.)</p><p>Don't let it replace human knowledge-sharing, though. Pair programming and code review still matter because they build judgment, not just transfer facts. Use AI for the "where is X?" questions so humans can focus on the "why did we decide X?" conversations that actually require dialogue.</p><pre><code>Audit this codebase for bus-factor risk and produce documentation that
reduces it. The goal: any engineer should be able to answer "how does X
work?" by reading what you produce, without waiting for the one person who
built it. Look for:

1. Subsystems where git blame is dominated by a single author
2. Modules with no documentation, sparse comments, and non-obvious behavior
3. Critical paths (auth, payments, data migrations, anything customer-facing)
   that lack runbooks or onboarding notes
4. Tribal knowledge encoded in code review history, commit messages, or
   PR descriptions but not in any document a new engineer would find

For each high-risk area, produce a short knowledge doc covering: what the
subsystem does, how it works at a high level, why it's designed this way
(cite sources when you can), the failure modes worth knowing about at 2am,
and where to look first when debugging.

Ground every claim in specific files, functions, and line ranges. Skip
what's obvious from reading the code - focus on the why and the gotchas.
If two parts of the codebase contradict each other, say so. Mark anything
you couldn't determine as "needs human input" rather than inventing.

Sort output by bus-factor risk: highest concentration of single-author
ownership first.</code></pre><h2>Schedule the Prompts</h2><p>You don't have to run these prompts manually. Claude Code has a <code>/schedule</code> slash command that sets up recurring runs as "routines" - saved configurations that fire on a schedule, clone your repo, and write back a report or open a PR. The Cowork tab in the Claude app does the same thing for people who'd rather not be in the terminal.</p><p>The setup is a conversation. Claude asks what you want to schedule, then handles the boring stuff: converting plain English into cron, scoping tool permissions, picking a model, and adding repo-specific context so the agent isn't completely cold when it wakes up next Monday.</p><p>Here's me setting up the dead-code audit (truncated):</p><pre><code>❯ /schedule

● What should this agent do?

❯ [pasted the dead-code audit prompt]
  Let's use claude-opus-4-7. We can run it every Monday at 10 am.

● Quick conversion: 10am Monday America/Los_Angeles = 17:00 UTC.
  Cron: 0 17 * * 1.

  Here's the full config:
  - Name: Weekly dead-code audit
  - Schedule: 0 17 * * 1 (Mondays 10am PDT / 9am PST)
  - Model: claude-opus-4-7
  - Repo: dustinboston/dblogit-next
  - Tools: Read, Glob, Grep, Bash (read-only - analysis only)

  Prompt (your text, with a preamble so the agent has repo context):

      You are running a weekly dead-code audit on the dblogit-next repo
      (Next.js 16 App Router, TypeScript, Drizzle ORM, Vitest + Playwright).

      Focus on `src/`, `scripts/`, and `tests/`. Use Grep liberally to verify
      "unused" claims - search for the symbol across the whole repo, not
      just the file where it's defined. Remember that Next.js App Router
      files (page.tsx, layout.tsx, route.ts, server actions) are entrypoints
      and won't have explicit imports.

      [...original prompt...]

● Routine created.
  Next run: Mon, May 18, 10:08 AM PDT
  Manage: https://claude.ai/code/routines/trig_011f32v4Q9YuyH4xU1ZHTKBX</code></pre><p>A few things to notice. "10am Monday" turned into <code>0 17 * * 1</code> automatically. I didn't have to think about timezones or learn cron. Claude added a preamble to my prompt with the repo's stack and a note about Next.js entrypoint files not having explicit imports, which is the kind of context-setting that makes a cold-start agent useful instead of confused. Tools were locked to read-only because the audit is analysis, not changes. I asked for Opus 4.7 instead of the Sonnet default since these audits are worth a bit more thinking.</p><p>All of these prompts work as routines now that they're framed as codebase audits. Setting them up takes about a minute each, and then I just read the PRs that show up Monday morning. The routines surface the work; the <a href="https://dustin.boston/blog/vibe-coding-isnt-enough">engineer in the loop</a> still decides what to merge.</p><p>To reduce maintenance costs with AI, you don't need new advice. Most of it has been canon for decades, and every senior engineer would nod along reading the list. What changed is the cost. Maintenance work was always worth doing; it just wasn't affordable for most teams. Now it is.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[The Boring Internet is Wonderful, but it's Kinda a Lot of Work]]></title>
      <link>https://dustin.boston/blog/the-boring-internet-is-a-lot-of-work</link>
      <guid isPermaLink="true">https://dustin.boston/blog/the-boring-internet-is-a-lot-of-work</guid>
      <pubDate>Tue, 12 May 2026 03:24:00 GMT</pubDate>
      <description><![CDATA[The Boring Internet is a nice rah rah post about using old internet technologies. It's about The Old Ways.  It's just too bad the old ways are kind of a lot of effort....]]></description>
      <content:encoded><![CDATA[<p><a href="https://www.terrygodier.com/the-boring-internet">The Boring Internet</a> is a nice rah rah post about using old internet technologies. This is my response to it.</p><h3>Microsoft Exchange</h3><p>Something we used to do in the early 2000's was host from home. You'd load up your servers on an old Dell PC and point DNS at your IP. A million years ago, I happened to get a bunch of Microsoft server licenses. I went ham and installed everything: Microsoft Exchange, Microsoft SQL Server, IIS, the works. Then one day there was a really bad storm that knocked the power out at my house. The Exchange server happened to be in the middle of indexing, and I lost a lot of email from family and friends. But it wasn't worth the effort to restore.</p><p>Then ISPs started blocking port 80. You had to do the work-around with dynamic DNS. Over time it just became a lot of effort. Editing config files, trying to understand all the quirky Windows UIs. Keeping the server up to date. Eventually I decided to stop hosting from home.</p><h3>Self-Hosting on a VPS</h3><p>I ran my own email server on Digital Ocean and self-hosted my websites with <a href="https://mailinabox.email/">Mail-in-a-box</a>. For the most part, it was pretty low touch. But those upgrades between Ubuntu versions were rough. The thing with Mail-in-a-box is that if you use all the features (i.e. Nextcloud), and if you have more than one user (I had my whole family on board), the costs start to go up. It was going to end up costing me a lot to keep up with the storage needs of the family. I finally got tired of being tech support and devops, so I took it all down, moved to Gmail like everyone else and started hosting on GitHub pages.</p><h3>Application Hosting</h3><p>But that left me wanting more from my websites. I vibe coded up a Next.js application and slid on over to Vercel. Now I live in fear of making it on Hacker News. I'm basically spending more time and money maintaining my websites than I ever have before. I'm paying for a SQLite database for crying out loud. It's a freaking file. They just make it so easy.</p><h3>The Boring Internet is Kinda a Lot of Work</h3><p>The point of all this rambling is that doing it The Old Way is great and nostalgic, but it also takes a lot of effort to keep it all going. And with every innovation there is an even higher financial cost. But Godier's right that the protocols are still there. SMTP didn't go anywhere, nobody took DNS public, the boring internet is humming along just fine.</p><p>What the essay doesn't quite say is that the cost of being a small participant on those protocols has quietly gone up. Running an MX record in 2003 meant your server was a peer on the network. Running one in 2026 means begging Gmail to like you so they don't send all of your email directly to spam. The protocols haven't changed but maybe the social contract around them has.</p><p>So my version of the boring internet is a little more bittersweet. I love that it's all still there. I want to be there. Maybe the next move is back down. Honestly though, I'm not sure I have the energy. That, I think, is what the veneer is really made of: convenience compounding until the alternatives feel like work.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Using HTML instead of Markdown with AI]]></title>
      <link>https://dustin.boston/blog/using-html-instead-of-markdown-with-ai</link>
      <guid isPermaLink="true">https://dustin.boston/blog/using-html-instead-of-markdown-with-ai</guid>
      <pubDate>Mon, 11 May 2026 01:35:00 GMT</pubDate>
      <description><![CDATA[Tariq argues that using HTML is better than Markdown for AI tasks....]]></description>
      <content:encoded><![CDATA[<p>This <a href="https://x.com/trq212/status/2052809885763747935">post on X from Thariq</a> has been making the rounds. The idea is that HTML is a better format than Markdown for AI. </p><p>I've been creating a lot of single page applications (SPAs) similar to <a href="https://tools.simonwillison.net/">Simon Willison's Tools page</a> but it hadn't occurred to me to use HTML as an output format. Here are the basic arguments Tariq makes:</p><ol><li><p>Markdown is becoming limiting</p></li><li><p>HTML has richer information density</p></li><li><p>HTML improves readability</p></li><li><p>It's easy to share HTML</p></li><li><p>Use cases span the SDLC</p></li></ol><p>There are a few downsides though:</p><ul><li><p>HTML uses more tokens</p></li><li><p>HTML takes longer to generate</p></li><li><p>HTML is worse for diffs</p></li></ul><p>I'll have to give this a try to see how it works.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Employee Surveillance for AI Training: 5 Reasons Meta's Jaw-Dropping Tracking is Unethical]]></title>
      <link>https://dustin.boston/blog/employee-surveillance-for-ai-training-is-unethical</link>
      <guid isPermaLink="true">https://dustin.boston/blog/employee-surveillance-for-ai-training-is-unethical</guid>
      <pubDate>Sun, 10 May 2026 15:35:00 GMT</pubDate>
      <description><![CDATA[Meta's use of employee surveillance for AI training is unethical in at least five ways....]]></description>
      <content:encoded><![CDATA[<p><a href="https://www.nytimes.com/2026/05/08/technology/meta-ai-employees-miserable.html?unlocked_article_code=1.hlA.e7db.KEPn-Z5TrBJl&amp;smid=url-share&amp;utm_source=tldrnewsletter">Meta’s Embrace of A.I. Is Making Its Employees Miserable</a> discusses how Meta is now tracking everything that employees do on their computers, specifically:</p><blockquote><p>What employees typed into their computer, how they moved their mouse, where they clicked and what they saw on their screen would be tracked, Meta said. The goal, the company said, was to capture employee data so Meta’s artificial intelligence models could learn “how people actually complete everyday tasks using computers.”</p></blockquote><p>Here are five reasons that this is absolutely bonkers, and how employee surveillance for AI training is unethical.</p><h3>1. No way to opt out</h3><p>When an engineering manager asked Andrew Bosworth, CTO of Meta, about how to opt out, Bosworth noted that is not an option. Sure, the computers that employees use are property of Meta. And Meta can legally do whatever they want with their own devices. But that doesn't make it ethical. Ethical would mean that an employee has given consent to the collection of their data. But since Meta knew that nobody would consent, they made it into an issue of compliance. Now employment is conditional upon acceptance of surveillance. Employees weren't told about this policy when they were hired. Now they have to make the decision to stay with the company or quit, there's no real choice.</p><h3>2. Coercive timing</h3><p>Here's why I say there was no real choice. Facebook said they would lay off 10% of their workforce. Rolling out a plan to surveil employees weeks before layoffs was strategically timed to get people to leave. But if you think about it, folks generally aren't going to leave right before layoffs. The thinking is that It's better to stick it out and collect severance pay than quit on ethical grounds and get nothing. Meta may say that these events have nothing to do with each other. But it doesn't matter. The conditions of free choice were not there regardless of intent. Add Meta to <a href="https://dustin.boston/blog/the-layoffs-continue-with-coinbase-paypal-and-cloudflare">the layoffs wall of shame</a>.</p><h3>3. Training replacements</h3><p>In the Times article Susan Li, CFO of Meta, hinted that the size of the company would change due to A.I. capabilities.</p><blockquote><p>We don't really know what the optimal size of the company will be in the future... I think there's a lot of change right now, with A.I. capabilities advancing rapidly.</p></blockquote><p>Janelle Gale, the HR head, made it explicit in an internal message:</p><blockquote><p>The cuts will allow the company “to offset the other investments we’re making,” Janelle Gale, Meta’s head of human resources, said in an internal message. She added, “I know this leaves everyone with nearly a month of ambiguity which is incredibly unsettling.”</p></blockquote><p>How humiliating - train your own replacement - just to be let go. Let me spell this out. The company announces that there are going to be layoffs and then they say employee surveillance for AI training is mandated.</p><h3>4. Sharing PII with Meta</h3><p>Personally Identifiable Information (PII) <em>will</em> get swept up in the screen and keystroke capture. For example, when you type a password the keylogger will just eat it right up. It could also Hoover up health information, personal messages, confidential information. If they track the clipboard as well, there's literally no safe way to enter a password.</p><h3>5. Inefficiency</h3><p>AI doesn't need to watch you use your computer, because AI doesn't need to use a computer that way. I'll restate it differently. AI doesn't have the same constraints that humans have. Why tie AI to a slow user interface when it can operate a system using Unix-style commands at a much faster pace. "OK, wise guy," I hear you saying. "What if there are legacy apps with no APIs. AI could interact with it." Well, you're right, as long as you're not concerned about performance, compute per task, or visual parsing errors. Even if none of this was an issue, <a href="https://dustin.boston/blog/ai-will-create-more-engineering-work-not-less">AI is still going to create more engineering work</a> (in a good way).</p><h3>And more...</h3><ul><li><p>Zuckerberg's "not for surveillance" line collides with token dashboards already tied to <a href="https://dustin.boston/blog/ai-usage-as-a-factor-in-performance-reviews">performance reviews</a>.</p></li><li><p>"Agents to find agents" is Goodhart's Law in real time (when a measure becomes a target, it ceases to be a good measure).</p></li><li><p>The idea that there "will not be a leak risk" is indefensible, but readers have heard this concern about every data program.</p></li><li><p>It sets a bad industry precedent. We don't want even more companies surveilling their employees.</p></li></ul><h3>Employee surveillance for AI training is unethical</h3><p>The case against Meta's program isn't that surveillance is new, or that AI training is inherently wrong, or that employees have an absolute right to privacy on corporate devices. But meaningful consent requires the genuine ability to refuse, and Meta has explicitly removed that ability. When the CTO confirms there is no opt-out. When the rollout lands three weeks before an 8,000-person layoff. When the data being captured includes keystrokes, screen content, and mouse movement. What's being asked of employees is not participation in a data program. It's compliance with a condition of continued employment, on terms they had no role in setting.</p><p>That's what makes employee surveillance for AI training ethically distinct from ordinary workplace monitoring. The traditional justification for watching workers is operational (security, productivity, legal compliance). Here, employees are being conscripted for commercial AI products, under conditions where objecting carries real career risk and the technical premise (that AI must learn by watching humans use computers) is itself a choice rather than a necessity.</p><p>The deeper problem isn't any single design decision but the pattern they form together: a company with the engineering capacity to do this differently has chosen the path that extracts the most from the people with the least power to say no. Whatever the eventual capabilities of the resulting AI, the precedent being set - that workforce-scale behavioral capture is an acceptable cost of staying competitive - is one other employers will follow, and one that will be much harder to walk back than it was to begin.</p><p>Here's a picture of a kid to calm your nerves. Just look at those tiny horns and that devilish grin. (Photo by <a href="https://www.flickr.com/photos/el-milligano/">Gordon Milligan</a>)</p><img src="https://live.staticflickr.com/3858/15324522455_2e2b739f72_k.jpg" ><h3></h3><p></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[The Layoffs Continue with Coinbase, PayPal, and Cloudflare]]></title>
      <link>https://dustin.boston/blog/the-layoffs-continue-with-coinbase-paypal-and-cloudflare</link>
      <guid isPermaLink="true">https://dustin.boston/blog/the-layoffs-continue-with-coinbase-paypal-and-cloudflare</guid>
      <pubDate>Fri, 08 May 2026 07:29:00 GMT</pubDate>
      <description><![CDATA[This time it's Coinbase, PayPal, and Cloudflare who all cite AI as a primary driver. These companies are hurting real people....]]></description>
      <content:encoded><![CDATA[<p>This time it's <a href="https://www.coinbase.com/blog/building-a-leaner-and-faster-coinbase">Coinbase</a>, <a href="https://finance.yahoo.com/markets/stocks/articles/paypal-layoffs-ceo-cuts-20-154944985.html">PayPal</a>, and <a href="https://blog.cloudflare.com/building-for-the-future/">Cloudflare</a> who all cite AI as a primary driver. See the <a href="https://layoffs.fyi/">layoffs wall of shame</a>. These companies are hurting real people, in the tens of thousands. It's not just a "hard decision." The hard decision would be to keep these employees and let natural attrition take care of the rest. Sure, it takes longer and it doesn't free up money for <a href="https://read.engineerscodex.com/p/tokenmaxxing-promomaxxing-and-misaligned">tokenmaxxing</a> - could it get any more wasteful? People should be more important than profits.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Mullenweg Creates a Tiger Team to Overhaul Wordpress.org]]></title>
      <link>https://dustin.boston/blog/mullenweg-creates-a-tiger-team-to-overhaul-wordpressorg</link>
      <guid isPermaLink="true">https://dustin.boston/blog/mullenweg-creates-a-tiger-team-to-overhaul-wordpressorg</guid>
      <pubDate>Fri, 08 May 2026 07:19:00 GMT</pubDate>
      <description><![CDATA[Matt Mullenweg recently gave a small group of trusted contributors the authority to overhaul the site without approval....]]></description>
      <content:encoded><![CDATA[<p><a href="https://www.therepository.email/matt-mullenweg-assembles-trusted-group-to-overhaul-wordpress-org-and-five-for-the-future?utm_source=tldrnewsletter">Matt Mullenweg Assembles Trusted Group to Overhaul WordPress.org and Five for the Future</a></p><blockquote><p>Changes have been rolling out across WordPress.org after Matt Mullenweg recently created a new channel on WordPress Slack, giving a small group of trusted contributors the authority to overhaul the site without approval from any team, committee, or stakeholder other than himself.</p></blockquote><p>Interesting that just 12 people have been granted access. We used this same "Tiger Team" approach at Disney when we migrated Hulu into the Disney platform. Small teams with broad authority can move much faster. It's a good call, but it's a Band-Aid.  Once the overhaul is complete, and the team is disbanded, who will keep the site from rotting again? </p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[The database gods have shown their favor]]></title>
      <link>https://dustin.boston/blog/the-database-gods-have-shown-their-favor</link>
      <guid isPermaLink="true">https://dustin.boston/blog/the-database-gods-have-shown-their-favor</guid>
      <pubDate>Thu, 07 May 2026 18:54:00 GMT</pubDate>
      <description><![CDATA[I was adding some new functionality to the site, and I made a mistake that resulted in the loss of all of my posts for several hours....]]></description>
      <content:encoded><![CDATA[<p>I was adding some new functionality to the site: display featured posts on the home page. Tag a post as featured by clicking a star icon. ez - but noOoOoo, things had to go and get all complicated. I made the change to <code>ALTER</code> the posts table with the featured flag. I know, it probably should have gone in a separate table but whatever. You already know where this is going. </p><p>I accidentally truncated the whole posts table because of a misunderstanding about how Drizzle works. But hey, I didn't panic so that's good. What I did do: looked for a backup, realized it was two months old, cursed my own name. Then, I pieced together whatever I could, which was about 30 posts short of what I actually had. I restored it and found a bug in my restore logic. Of course. Yack shaving time. </p><p>Fast forward a couple of hours. The fix was in. I had to truncate the tags/posts table because the IDs for the posts I found were different from the post IDs in the lookup table. That caused an error when I tried to import. Still missing about 30 posts. </p><p>As I was combing through my downloads folder, I found a full backup from days ago. I don't even remember making it. Thank the database gods. </p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Chrome released loading=lazy for video and audio elements]]></title>
      <link>https://dustin.boston/blog/chrome-released-loading-lazy-for-video-and-audio-elements</link>
      <guid isPermaLink="true">https://dustin.boston/blog/chrome-released-loading-lazy-for-video-and-audio-elements</guid>
      <pubDate>Thu, 07 May 2026 18:45:00 GMT</pubDate>
      <description><![CDATA[Chrome 148 now supports lazy loading for video and audio elements. None of the other browsers support it yet....]]></description>
      <content:encoded><![CDATA[<p>Chrome 148 now supports <a href="https://developer.chrome.com/release-notes/148#lazy_loading_for_video_and_audio_elements">lazy loading for video and audio elements</a>. None of the other browsers support it yet. But, thanks to the power of the web, you can still add the attribute, and it will be silently ignored by all the other browsers. Here's the blurb from the release notes:</p><blockquote><p>Adds the loading attribute to <code>video</code> and <code>audio</code> elements, letting developers defer media resource loading until the element is near the viewport using <code>loading="lazy"</code>. This matches the existing lazy loading behavior for and elements, improving page load performance and reducing data usage.</p></blockquote><p>They also shipped a new <a href="https://developer.chrome.com/release-notes/148#prompt_api">prompt API</a>. Nobody's happy about that.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Blog Post SEO Ranking in 2026 (a Stupid Experiment)]]></title>
      <link>https://dustin.boston/blog/blog-post-seo-ranking-in-2026</link>
      <guid isPermaLink="true">https://dustin.boston/blog/blog-post-seo-ranking-in-2026</guid>
      <pubDate>Thu, 07 May 2026 18:30:00 GMT</pubDate>
      <description><![CDATA[All about blog post SEO ranking in 2026...]]></description>
      <content:encoded><![CDATA[<p>The following is a blog post designed to test what blog post SEO is like in 2026. It has been edited to fit the criteria from the <a href="https://wordpress.org/plugins/seo-by-rank-math/">Rank Math SEO plugin for WordPress</a>. I've used one keyword, "blog post SEO," throughout the article. You don't have to read it: the example post is AI generated, so proceed accordingly. Here's the Rank Math criteria:</p><ul><li><p>There's a keyword in the title. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-seo-title-primary-focus-keyword-only" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-seo-title-primary-focus-keyword-only">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#keywords-in-title-and-description-test" title="https://rankmath.com/kb/seo-analysis/#keywords-in-title-and-description-test">[topic]</a> (weight 7)</p></li><li><p>And it's at the beginning. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-at-the-beginning-of-the-seo-title-only-for-primary-keyword" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-at-the-beginning-of-the-seo-title-only-for-primary-keyword">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#post-titles-missing-focus-keywords-test" title="https://rankmath.com/kb/seo-analysis/#post-titles-missing-focus-keywords-test">[topic]</a> (weight 4)</p></li><li><p>There's also a keyword in the meta description. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-meta-description-primary-focus-keyword-only" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-meta-description-primary-focus-keyword-only">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#keywords-in-title-and-description-test" title="https://rankmath.com/kb/seo-analysis/#keywords-in-title-and-description-test">[topic]</a> (weight 6)</p></li><li><p>And in the URL slug. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-url-primary-focus-keyword-only" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-url-primary-focus-keyword-only">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#permalink-structure-test" title="https://rankmath.com/kb/seo-analysis/#permalink-structure-test">[topic]</a> (weight 5)</p></li><li><p>There's a keyword in the content. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-content-runs-on-all-focus-keywords" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-the-content-runs-on-all-focus-keywords">[kb]</a> (weight 6)</p></li><li><p>And it appears in the first 10%. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-at-the-beginning-of-the-content-primary-focus-keyword-only" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-at-the-beginning-of-the-content-primary-focus-keyword-only">[kb]</a> (weight 5)</p></li><li><p>At least one subheading contains a keyword. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-subheading-primary-and-secondary-focus-keywords" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-subheading-primary-and-secondary-focus-keywords">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#h2-headings-test" title="https://rankmath.com/kb/seo-analysis/#h2-headings-test">[topic]</a> (weight 5)</p></li><li><p>The keyword appears in image alt text. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-image-alt-attributes-primary-focus-keyword-only" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-in-image-alt-attributes-primary-focus-keyword-only">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#image-alt-attributes-test" title="https://rankmath.com/kb/seo-analysis/#image-alt-attributes-test">[topic]</a> (weight 5)</p></li><li><p>Keyword density is between 0.75 and 2.5. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#keyword-density-primary-and-secondary-focus-keywords" title="https://rankmath.com/kb/score-100-in-tests/#keyword-density-primary-and-secondary-focus-keywords">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#common-keywords-test" title="https://rankmath.com/kb/seo-analysis/#common-keywords-test">[topic]</a> (weight 6)</p></li><li><p>Focus keyword has not been used on another post. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-uniqueness-primary-focus-keyword-only" title="https://rankmath.com/kb/score-100-in-tests/#focus-keyword-uniqueness-primary-focus-keyword-only">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#focus-keywords-test" title="https://rankmath.com/kb/seo-analysis/#focus-keywords-test">[topic]</a> (weight 4)</p></li><li><p>Content is &gt;= 2,500 words long. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#overall-content-length" title="https://rankmath.com/kb/score-100-in-tests/#overall-content-length">[kb]</a> (weight 7)</p></li><li><p>URL slug is less than or equal to <strong>75 characters</strong>. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#url-length" title="https://rankmath.com/kb/score-100-in-tests/#url-length">[kb]</a><a class="help" href="https://rankmath.com/kb/seo-analysis/#permalink-structure-test" title="https://rankmath.com/kb/seo-analysis/#permalink-structure-test">[topic]</a> (weight 3)</p></li><li><p>Content has at least 1, preferably three or more internal links. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#linking-to-internal-resources" title="https://rankmath.com/kb/score-100-in-tests/#linking-to-internal-resources">[kb]</a> (weight 5)</p></li><li><p>Content has at least one external link. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#linking-to-external-sources" title="https://rankmath.com/kb/score-100-in-tests/#linking-to-external-sources">[kb]</a> (weight 5)</p></li><li><p>Content mixes internal and external links. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#linking-to-external-content-with-a-followed-link" title="https://rankmath.com/kb/score-100-in-tests/#linking-to-external-content-with-a-followed-link">[kb]</a> (weight 3)</p></li><li><p>There is a sentiment word (<a href="https://gist.github.com/mkulakowski2/4289437#file-positive-words-txt">positive</a> or <a href="https://github.com/jeffreybreen/twitter-sentiment-analysis-tutorial-201107/blob/master/data/opinion-lexicon-English/negative-words.txt">negative</a>) title. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#sentiment-in-a-title" title="https://rankmath.com/kb/score-100-in-tests/#sentiment-in-a-title">[kb]</a> (weight 3)</p></li><li><p>A <a href="https://rankmath.com/blog/power-words/#power-words-list">power word</a> is in title. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#use-of-power-word-in-title" title="https://rankmath.com/kb/score-100-in-tests/#use-of-power-word-in-title">[kb]</a><a class="help" href="https://rankmath.com/blog/power-words/" title="https://rankmath.com/blog/power-words/">[blog]</a> (weight 3)</p></li><li><p>The title contains a number. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#number-in-title" title="https://rankmath.com/kb/score-100-in-tests/#number-in-title">[kb]</a> (weight 3)</p></li><li><p>There is a table of contents. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#use-a-table-of-contents-to-present-your-content-better" title="https://rankmath.com/kb/score-100-in-tests/#use-a-table-of-contents-to-present-your-content-better">[kb]</a> (weight 3)</p></li><li><p>All paragraphs are under 120 words. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#use-of-short-paragraphs" title="https://rankmath.com/kb/score-100-in-tests/#use-of-short-paragraphs">[kb]</a> (weight 6)</p></li><li><p>There are images or media. <a class="help" href="https://rankmath.com/kb/score-100-in-tests/#use-of-media-in-your-posts" title="https://rankmath.com/kb/score-100-in-tests/#use-of-media-in-your-posts">[kb]</a> (weight 6)</p></li></ul><hr><img src="https://placehold.co/600x400/EEE/31343C" alt="Blog Post SEO can be accomplished with online tools" ><h3>Table of Contents</h3><ul><li><p><a href="#start-with-intent">Start With Intent, Not Keywords</a></p></li><li><p><a href="#keyword-research">Do Real Keyword Research for Blog Post SEO</a></p></li><li><p><a href="#first-hand-experience">Write With First-Hand Experience</a></p></li><li><p><a href="#headline-and-intro">Nail the Headline and First 100 Words</a></p></li><li><p><a href="#ai-search">Modern Blog Post SEO Means Optimizing for AI Search</a></p></li><li><p><a href="#topical-authority">Build Topical Authority, Not Orphan Posts</a></p></li><li><p><a href="#technical-fundamentals">Get the Technical Fundamentals Right</a></p></li><li><p><a href="#earn-links">Earn Links the Slow Way</a></p></li><li><p><a href="#format">Match Format to Reader Behavior</a></p></li><li><p><a href="#voice-and-visual">Don't Ignore Voice and Visual Search</a></p></li><li><p><a href="#update-old-posts">Update Old Posts Ruthlessly</a></p></li><li><p><a href="#track-metrics">Track What Matters, Ignore What Doesn't</a></p></li><li><p><a href="#be-patient">Be Patient</a></p></li><li><p><a href="#have-i-ranked">Have I Ranked?</a></p></li></ul><h3>Start With Intent, Not Keywords</h3><p>Ranking a blog post in 2026 is less about gaming the algorithm and more about being the best answer for a real query. Modern blog post SEO rewards depth, originality, and intent-matching far more than keyword tricks.</p><p>Before you write a word, search the term you're targeting and study the top 10 results. What format is winning — a listicle, a deep guide, a comparison, a how-to? What questions do they answer? What do they miss? Your job isn't to mimic them; it's to write something that makes them look incomplete. A post targeting "best running shoes for flat feet" beats anything generic about running shoes — match the specific intent or don't bother.</p><p>Search intent generally falls into four buckets: informational ("how does compound interest work"), navigational ("Rank Math login"), commercial ("best email marketing tools"), and transactional ("buy noise canceling headphones"). Each demands a different post structure. Informational queries want thorough explainers with diagrams. Commercial queries want comparison tables, pros and cons, and clear recommendations. Mismatching intent is the single most common reason a well-written post fails to rank — and it's the foundation of all good blog post SEO. Google has decided what searchers want, and you don't get to override that with great prose alone.</p><h3>Do Real Keyword Research for Blog Post SEO</h3><p>Keywords aren't dead — they're just not the whole game. Effective blog post SEO still requires knowing which terms people actually search for, how often, and how hard they are to rank for. Free tools like <a href="https://ads.google.com/home/tools/keyword-planner/">Google Keyword Planner</a>, <a href="https://trends.google.com/">Google Trends</a>, and <a href="https://answerthepublic.com/">AnswerThePublic</a> give you a starting point. Paid tools like <a href="https://ahrefs.com/">Ahrefs</a>, <a href="https://www.semrush.com/">Semrush</a>, and <a href="https://mangools.com/">Mangools</a> go deeper with difficulty scores, click-through rate estimates, and SERP analysis.</p><p>The trick is targeting keywords you can actually win. A new site has no business chasing "credit cards" — that's a battlefield owned by NerdWallet and Bankrate. But "best credit cards for freelancers with irregular income" might have only a handful of mediocre results competing for it. Long-tail keywords (three or more words, more specific) typically have lower volume but much higher conversion intent and far less competition. Build your content calendar around these wins, then graduate to harder terms as your site's authority grows.</p><p>One more nuance: don't optimize a single post for one keyword. A modern approach to blog post SEO targets a primary keyword plus 10–30 semantically related terms. Google's algorithms reward content that comprehensively covers a topic, not content that mentions one phrase repeatedly.</p><h3>Write With First-Hand Experience</h3><p>Google's helpful content system and the rise of AI Overviews have made one thing clear: the web doesn't need another summary of summaries. If you've actually done the thing, tested the product, or worked in the field, that signal — the "E" in E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness) — shows up in screenshots, original photos, specific numbers, and opinions other articles wouldn't risk. Pure AI-generated rewrites of existing content are getting filtered out at scale.</p><p>Practical ways to inject experience into a post: include before-and-after screenshots from your own dashboard, share specific numbers from your own results (revenue, traffic, time saved), name the exact tools and versions you used, describe a mistake you made and what it cost you, and quote real conversations with experts in your field.</p><p>A post titled "How I Reduced My Page Load Time From 4.2s to 0.8s" will outperform "How to Speed Up Your Website" every time, because the first signals lived experience and the second smells like AI slop. Experience is the most underrated input in blog post SEO.</p><h3>Nail the Headline and First 100 Words</h3><p>Most readers (and AI summarizers) decide whether your post is worth their attention in the first few seconds. Your H1 should promise a specific outcome, not tease it — "How to Cut Your AWS Bill by 40% in a Weekend" beats "Saving Money on Cloud Hosting" every time. Then deliver on that promise immediately. The opening paragraph should answer the core question or state the thesis up front, with the supporting detail below. This isn't just good writing; it's how AI Overviews and featured snippets pick which passage to quote. Burying the lede in 2026 means burying your traffic.</p><p>The same logic applies to your meta description and title tag, which appear in search results. The title tag should include your primary keyword near the beginning and stay under 60 characters so it doesn't get truncated. The meta description (around 155 characters) doesn't directly affect rankings, but it heavily influences click-through rate, which does. Write it like ad copy: include the keyword, hint at the value, and create a small reason to click. A post that ranks #3 with a great snippet often gets more traffic than a post that ranks #1 with a boring one.</p><h3>Modern Blog Post SEO Means Optimizing for AI Search</h3><p>A growing share of searches now end inside Google's AI Overviews, ChatGPT, Perplexity, and similar tools without a click to your site. To get cited in those answers, structure content so individual passages can stand alone: clear question-style subheadings, direct answers in the first sentence under each, and definitive statements rather than wishy-washy hedging. Schema markup is now a core part of blog post SEO — FAQ, HowTo, Article, and Product schemas help machines understand what your page is about and increase your chances of being surfaced.</p><p>The data backs this up. The <a href="https://dustin.boston/blog/summary-of-the-http-archive-2025-web-almanac">2025 Web Almanac</a> found that AI systems are beginning to rely on the same SEO practices that have always served human searchers — but with a twist: visibility now means being understood by AI, not just crawled. Crawlability and indexability are getting more complex as bots multiply and rendering paths fragment, while the fundamentals like consistent titles and headings remain stable (meta descriptions are even rebounding after years of decline). On the structured data front, JSON-LD is now the dominant format for schema markup and AMP has fallen below 1% adoption — so if you're still wiring up AMP pages, stop, and put that energy into JSON-LD instead.</p><p>This shift toward "zero-click" search means your job has split in two: you still want clicks, but you also want to be the source AI tools cite when they don't send a click. Citations build brand recognition and authority over time, even when traffic doesn't immediately follow. Original research, unique data points, and clear definitions are particularly likely to be quoted. If you publish a stat in 2026, expect it to show up in someone's AI-generated answer next month — make sure your name is attached.</p><h3>Build Topical Authority, Not Orphan Posts</h3><p>One great article on a niche site usually outranks a great article on a generalist site, because Google rewards depth in a subject. Plan content in clusters — a pillar post plus 5–10 supporting pieces that link inward — rather than a scattershot of unrelated topics. Internal linking with descriptive anchor text is one of the most underused on-page levers.</p><p>Here's how a content cluster works in practice. Say you run a personal finance blog. Your pillar post might be "The Complete Guide to Index Fund Investing" — a 4,000-word definitive resource. Around it, you build supporting posts: "VTSAX vs VTI: Which Should You Choose?", "How to Open a Vanguard Account in 10 Minutes", "Tax-Loss Harvesting With Index Funds", and so on. Each supporting post links to the pillar, and the pillar links out to each supporting post. Google sees this network and concludes your site has genuine depth on index fund investing — and starts ranking all the posts higher together. This is blog post SEO at the architectural level, not the page level.</p><h3>Get the Technical Fundamentals Right</h3><p>A post that takes four seconds to render on mobile won't rank no matter how good it is. Compress images, use a fast theme, and pass Core Web Vitals. Make sure your title tag is compelling and under about 60 characters, your meta description is genuinely useful (not stuffed), your URL is short and readable, and every image has descriptive alt text. None of this technical blog post SEO ranks you alone, but missing it bleeds rankings you've already earned.</p><p>Core Web Vitals deserve specific attention. Google measures three things: Largest Contentful Paint (how fast the main content loads, target under 2.5 seconds), Interaction to Next Paint (how quickly the page responds to clicks and taps, target under 200ms), and Cumulative Layout Shift (how much the page jumps around as it loads, target under 0.1). Run any post through <a href="https://pagespeed.web.dev/">PageSpeed Insights</a> and fix what's flagged. The most common culprits are unoptimized images, render-blocking JavaScript, and too many third-party scripts (analytics, chat widgets, ad networks). Each one you remove typically buys back hundreds of milliseconds.</p><h3>Earn Links the Slow Way</h3><p>Backlinks are still one of the strongest ranking signals, and there's no shortcut that lasts. The reliable plays are creating original data or research worth citing, writing the definitive piece on something underserved, and being a real person on social platforms where journalists and bloggers in your space hang out.</p><p>What doesn't work in 2026: buying links, mass guest posting on low-quality sites, private blog networks, and "link exchanges." Google's algorithms catch these reliably, and the penalty often outweighs years of legitimate work. What does work: publishing original studies (even small ones — a survey of 200 people in your niche can generate dozens of links), creating free tools that solve a specific problem, contributing thoughtful guest posts to genuinely respected publications in your industry, and building relationships with journalists by being responsive on platforms like Source of Sources (the spiritual successor to HARO, which shut down in late 2024), <a href="http://Featured.com">Featured.com</a>, or Qwoted. Quality over quantity always — five links from authoritative sites in your niche outweigh 500 links from random directories.</p><h3>Match Format to Reader Behavior</h3><p>Walls of text lose. Today's readers scan first and read second, especially on mobile, where most of your traffic now lives. Break content with descriptive subheadings every 200–300 words, use short paragraphs (2–4 sentences), and lean on bulleted or numbered lists when you're enumerating steps or items. Add a table when you're comparing options — Google often pulls tables directly into search results. Embed an original chart, diagram, or annotated screenshot if you can; visual assets keep readers on the page longer, which sends positive engagement signals, and they're far more likely to attract organic backlinks than another wall of prose.</p><p>Pay attention to readability too. Tools like <a href="https://hemingwayapp.com/">Hemingway Editor</a> flag passive voice, complex sentences, and reading-level scores. Most blog content should land at a 7th-to-9th-grade reading level — not because your audience is unsophisticated, but because clarity beats cleverness. Even academic readers prefer clean prose when they're skimming for an answer. Save your literary flourishes for fiction.</p><h3>Don't Ignore Voice and Visual Search</h3><p>Roughly 30% of searches now happen by voice, and visual search (Google Lens, Pinterest Lens, AI tools that accept image inputs) is growing fast. Voice queries tend to be longer and more conversational — "what's the best way to remove a coffee stain from a white shirt" rather than "remove coffee stain shirt." Optimize for these by including natural-language questions as subheadings and answering them directly underneath. Visual search rewards properly tagged images: descriptive filenames (red-leather-handbag.jpg, not IMG_4823.jpg), thorough alt text, and image schema markup. If you sell products or feature objects in your content, treating images as a search surface — not just decoration — opens a traffic channel most competitors are ignoring in their blog post SEO strategy.</p><h3>Update Old Posts Ruthlessly</h3><p>Most blogs leave traffic on the table by publishing and forgetting. Twice a year, audit posts that rank on page two or are slipping. Update facts, add new sections, refresh examples, improve internal links, and republish with the new date. This is often higher-leverage than writing new content, and it's the single most overlooked tactic in blog post SEO.</p><p>A practical refresh checklist: update any statistics older than 18 months, swap out screenshots that show outdated UI, add a new section addressing a question that's emerged since publication, check that all outbound links still work and replace dead ones, look for new related posts you've written that could be linked internally, and rewrite the title and meta description if click-through rate is below 2%.</p><p>After republishing, request reindexing in <a href="https://search.google.com/search-console/about">Google Search Console</a> so the changes are picked up quickly. Posts I've refreshed have routinely jumped from position 12 to position 4 within a few weeks — for free, using content that already existed.</p><h3>Track What Matters, Ignore What Doesn't</h3><p>Vanity metrics will mislead you. Don't obsess over your <a href="https://rankmath.com/kb/score-100-in-tests/">Rank Math SEO score</a>, keyword density, or how many words you've written — none of these correlate strongly with rankings. (Rank Math themselves publish a guide on hitting 100/100 that's worth reading specifically so you understand what their score does and doesn't measure.)</p><p>Focus on the metrics that actually predict traffic: impressions and average position in Google Search Console, click-through rate on your title tags (anything under 2% on page one means your title needs work), and engagement signals like time on page and scroll depth in your analytics. If a post gets impressions but no clicks, the problem is your title or meta description. If it gets clicks but visitors bounce in seconds, the content didn't deliver on the promise.</p><p>Set up a simple monthly review. Pull your top 20 posts by traffic and look for trends — which are climbing, which are slipping, which haven't been touched in a year. Pull your bottom 20 posts and decide whether each is worth fixing, consolidating with another post, or deleting outright. Yes, deleting. Thin or outdated content actively hurts your site's overall authority because it dilutes your topical focus. Pruning 50 weak posts can improve rankings on the 200 you keep — counterintuitive but proven blog post SEO hygiene.</p><h3>Be Patient</h3><p>New posts on established sites can rank in days; new posts on new sites often take six months even when everything is right. Blog post SEO compounds — the value isn't in one post, it's in fifty posts working together over two years.</p><p>The hardest part of SEO is the gap between effort and result. You publish a great post, and nothing happens for weeks. You write another. Still nothing. Then in month four, the first post starts pulling in 50 visitors a day, and by month eight it's at 500. By month eighteen, you have a portfolio of posts each pulling steady traffic, and the cumulative effect is real. Most people quit in month three. The ones who keep showing up — publishing, refreshing, internal linking, building real authority — are the ones who eventually own their niches. There is no shortcut. There has never been a shortcut. The shortcut is starting two years ago, and the next-best time is today.</p><h3>Have I Ranked?</h3><p>You'll typically know your page has ranked when it starts showing up in search results for the keywords you targeted — but the easiest way to track this systematically is through <a href="https://search.google.com/search-console/about">Google Search Console</a>. Once your page is indexed (usually within a few days to a few weeks of publishing), check the Performance report and filter by the page URL. You'll see the queries it's appearing for, your average position, impressions, and clicks. A position of 1–10 means you're on page one; 11–20 means page two, and so on.</p><p>Don't trust what you see by Googling the keyword yourself — personalized results, your location, and search history all skew what you see, making it look like you rank higher than you actually do. Use an incognito window with location set neutrally, or better, a rank tracking tool like Ahrefs, Semrush, or the keyword tracker built into Rank Math Pro to monitor positions over time.</p><p>The clearest signal you've truly ranked is sustained organic traffic to the post showing up in your analytics — once Google sends you clicks consistently for a target query over a few weeks, you've earned the spot rather than just briefly visited it.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Use Git Log to Learn About a Codebase]]></title>
      <link>https://dustin.boston/blog/use-git-log-to-learn-about-a-codebase</link>
      <guid isPermaLink="true">https://dustin.boston/blog/use-git-log-to-learn-about-a-codebase</guid>
      <pubDate>Sat, 02 May 2026 03:26:00 GMT</pubDate>
      <description><![CDATA[I'm always interested in ways to get familiar with a codebase faster. This post goes over how to use git log in multiple ways to get an overview of the project and the company....]]></description>
      <content:encoded><![CDATA[<p>I'm always interested in <a href="https://dustin.boston/blog/a-senior-engineers-guide-to-learning-a-new-codebase">ways to get familiar with a codebase faster</a>. This post goes over how to use <code>git log</code> in multiple ways to get an overview of the project and the company.</p><blockquote><p>Five git log commands that diagnose a new codebase before you open a single file: code churn hotspots, bus factor, bug clusters, and crisis patterns.</p></blockquote><p>Here are the commands, for quick reference:</p><pre><code class="language-bash"># What changes the most?
git log --format=format: --name-only --since="1 year ago" | sort | uniq -c | sort -nr | head -20

# Who built this?
git shortlog -sn --no-merges

# Where do bugs cluster?
git log -i -E --grep="fix|bug|broken" --name-only --format='' | sort | uniq -c | sort -nr | head -20

# Is this project accelerating or dying?
git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c

# How often is the team firefighting?
git log --oneline --since="1 year ago" | grep -iE 'revert|hotfix|emergency|rollback'</code></pre><p>Source: <a href="https://piechowski.io/post/git-commands-before-reading-code/">The Git Commands I Run Before Reading Any Code</a></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Mistaken identity]]></title>
      <link>https://dustin.boston/blog/mistaken-identity</link>
      <guid isPermaLink="true">https://dustin.boston/blog/mistaken-identity</guid>
      <pubDate>Sun, 19 Apr 2026 09:30:00 GMT</pubDate>
      <description><![CDATA[Recently when I Googled myself, I found more than I expected!...]]></description>
      <content:encoded><![CDATA[<p>Don't you just hate it when someone who shares your exact first and last name goes and murders some dude outside of a gas station and gets sentenced to 45 years in prison and then all that comes up when someone searches for your name is that?</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Harness Memory Architecture]]></title>
      <link>https://dustin.boston/blog/harness-memory-architecture</link>
      <guid isPermaLink="true">https://dustin.boston/blog/harness-memory-architecture</guid>
      <pubDate>Tue, 14 Apr 2026 07:56:00 GMT</pubDate>
      <description><![CDATA[Here's how Claude Code handles memory....]]></description>
      <content:encoded><![CDATA[<p>Claude Code's memory architecture <a href="https://x.com/himanshustwts/status/2038924027411222533">works like this</a>:</p><ol><li><p>The user can create memories at any time with a slash command.</p></li><li><p>Memories go into a folder and then the memory index file is updated with a link to each memory.</p></li><li><p>The memory index file is injected into the system prompt.</p></li><li><p>On each turn extract memories from the conversation into memory files. GOTO #2</p></li><li><p>Memories are consolidated in the background once a day. </p></li></ol><p></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[How to Architect a Harness]]></title>
      <link>https://dustin.boston/blog/how-to-architect-a-harness</link>
      <guid isPermaLink="true">https://dustin.boston/blog/how-to-architect-a-harness</guid>
      <pubDate>Sun, 12 Apr 2026 17:45:00 GMT</pubDate>
      <description><![CDATA[Garry Tan, CEO of Y Combinator, outlines an architecture for a harness (a wrapper around a model) that relies almost entirely on skills, not code....]]></description>
      <content:encoded><![CDATA[<p>Garry Tan, CEO of Y Combinator, <a href="https://x.com/garrytan/status/2042925773300908103?s=12">outlines an architecture for a harness</a> (a wrapper around a model) that relies almost entirely on skills, not code.</p><p>He says that the productivity gap among 1x, 10x, and 100x engineers using AI coding agents has almost nothing to do with model quality. Instead, the difference comes from the architecture wrapped around the model. Tan calls this the harness, and the central claim is that the harness, not the model, determines whether someone gets mediocre results or transformative ones.</p><p>The idea is that modern models already know how to reason, synthesize, and write code. Model failures come from not understanding the specific environment they are working in. The harness exists to give the model the right context at the right moment, without overwhelming it with irrelevant information. Tan describes reading the leaked Claude Code source and discovering that the real magic is not in the model but in the wrapper that orchestrates it. Can confirm.</p><p>To explain how this works, Garry introduces five concepts: skill files, the harness, resolvers, latent and deterministic work, and diarization. These form the backbone of a system that can scale from simple tasks to complex knowledge work.</p><h3>1. Skill Files</h3><p>Skill files are reusable markdown documents that describe a process. They don’t tell the model <strong>what </strong>to do; they tell it <strong>how </strong>to do it. The user supplies the goal, and the skill supplies the method. Tan compares a skill file to a method call with parameters. A single skill can be invoked in many different contexts, producing different outcomes depending on the arguments. Tan argues that markdown is a better medium for encoding judgment and process than traditional code, because it matches the model’s native mode of thinking.</p><h3>2. The Harness</h3><p>The harness is the minimal program that runs the model. It loops the model, manages context, reads and writes files, and enforces safety. Tan warns against building a bloated harness full of tools and abstractions that slow everything down and clutter the context window. His ideal harness is thin, while the skills are fat. Modern software no longer needs to be precious or over‑engineered; it should be fast, narrow, and purpose‑built.</p><h3>3. Resolvers</h3><p>Resolvers act as routing tables for context. They decide what documents to load when a certain type of task appears. Without resolvers, developers tend to stuff everything into a single giant prompt, which degrades the model’s attention. With resolvers, the system loads only the relevant documents at the right time. Tan describes how their own massive CLAUDE.md file became unmanageable until they replaced it with a small resolver that pointed to the right documents on demand.</p><h3>4. Latent vs Deterministic Work</h3><p>The distinction between latent and deterministic work is another key idea. Latent space is where the model exercises judgment, interpretation, and synthesis. Deterministic space is where reliability matters: SQL queries, arithmetic, and other operations that must produce the same output every time. Problems arise when tasks that belong in deterministic space are forced into latent space. Scale forces us to handle queries deterministically.</p><h3>5. Diarization</h3><p>Diarization is the process of reading a large body of material and producing a <em>structured profile</em> that captures the essential judgments. This is something neither SQL nor RAG can do. It requires the model to read, compare, notice contradictions, and synthesize. Tan argues that diarization is the key to making AI useful for real knowledge work.</p><h3>Architecture</h3><p>These five ideas combine into a three‑layer architecture. At the top are the fat skills, which encode judgment and process. In the middle is the thin harness, which orchestrates the model. At the bottom is the deterministic layer, which handles reliable operations like database queries and file access. The guiding principle is to push intelligence upward into skills and push execution downward into deterministic tools.</p><p>The article ends with a principle: if a task will need to be done more than once, it should be codified into a skill. Skills become permanent upgrades. They never degrade, and they improve automatically when models improve. This compounding effect, not smarter models, is what produces the dramatic productivity gains described at the beginning.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Enterprise Project Checklist]]></title>
      <link>https://dustin.boston/blog/enterprise-project-checklist</link>
      <guid isPermaLink="true">https://dustin.boston/blog/enterprise-project-checklist</guid>
      <pubDate>Sat, 11 Apr 2026 02:16:00 GMT</pubDate>
      <description><![CDATA[Here in the age of AI, projects need to be perfect when they are released. I use this enterprise software project checklist to keep track of everything I need to do....]]></description>
      <content:encoded><![CDATA[<p>Here in the age of AI, projects need to be perfect when they are released. I use this enterprise software project checklist to keep track of everything I need to do. It's modularized into distinct, LLM-executable domains. Each module is designed as an isolated context block, allowing an orchestrator LLM to dispatch them to parallel worker agents. The format uses explicit boolean constraints and declarative validation states to ensure deterministic agent evaluations.</p><h3><strong>Module 1: Scaffolding &amp; Configuration</strong></h3><ul><li><p><strong>Domain:</strong> Project initialization, environment strictness, and repository metadata.</p></li></ul><ul><li><p><strong>Execution Independence:</strong> Can run immediately upon repository creation.</p></li></ul><ul><li><p><strong>Version Control (</strong><code>.gitignore</code><strong>):</strong> Must omit <code>node_modules</code>, build directories (<code>dist</code>/<code>build</code>), <code>.env</code> files, OS artifacts, and IDE configs.</p></li><li><p><strong>Configuration Validation:</strong> Environment variables must be validated at runtime startup (e.g., via Zod or Joi). No hardcoded credentials or environment-specific URIs in source code.</p></li><li><p><strong>System Documentation (</strong><code>CLAUDE.md</code><strong>):</strong> Must exist at root. Requires: system overview, package script definitions, environment setup steps, and architectural links.</p></li><li><p><strong>Licensing:</strong> Default to <code>CC BY-NC 4.0</code>. For proprietary code, <code>package.json</code> must state <code>"license": "SEE LICENSE IN &lt;filename&gt;"</code> and <code>"private": true</code>, with a corresponding custom license file.</p></li></ul><h3><strong>Module 2: Code Quality &amp; Type Safety</strong></h3><ul><li><p><strong>Domain:</strong> Static analysis and syntax enforcement.</p></li></ul><ul><li><p><strong>Execution Independence:</strong> Can run as a continuous background linting/typing agent.</p></li></ul><ul><li><p><strong>Type Strictness:</strong> TypeScript <code>tsconfig.json</code> must have <code>"strict": true</code>. Zero tolerance for <code>any</code> types, non-null assertions (<code>!</code>), or type casting (<code>as Type</code>).</p></li><li><p><strong>Linting Rules:</strong> Must implement <code>xo</code> configured for maximum strictness. Pre-commit hooks must block non-compliant code.</p></li><li><p><strong>Dependency Auditing:</strong> Lockfiles (<code>package-lock.json</code> / <code>yarn.lock</code> / <code>pnpm-lock.yaml</code>) must be present. Automated vulnerability scanning (e.g., <code>npm audit</code> or Dependabot) must pass with zero critical/high vulnerabilities.</p></li></ul><h3>Module 3: Architecture &amp; State</h3><ul><li><p><strong>Domain:</strong> System design, persistence layers, and local infrastructure.</p></li><li><p><strong>Execution Independence:</strong> Requires schema and system design definitions.</p></li></ul><ul><li><p><strong>Architectural Patterns:</strong> Enforce separation of concerns (e.g., controllers, services, repositories). File structure must reflect domain-driven or strictly layered architecture.</p></li><li><p><strong>Data Persistence:</strong> Database schemas (e.g., PostgreSQL for relational, Pinecone for vector data) must use migration scripts. No manual schema modifications.</p></li><li><p><strong>Containerization:</strong> Local dependencies (databases, cache, messaging queues) must run via <code>docker-compose.yml</code>. Applications should have multi-stage <code>Dockerfile</code> definitions for production builds.</p></li></ul><h3>Module 4: Security &amp; Safeguards</h3><ul><li><p><strong>Domain:</strong> Threat mitigation, access control, and data protection.</p></li><li><p><strong>Execution Independence:</strong> Can review PRs for security anti-patterns in parallel with testing.</p></li></ul><ul><li><p><strong>Secrets Management:</strong> All cryptographic keys, API tokens, and database credentials must be encrypted at rest and injected via secure managers (e.g., AWS Secrets Manager, HashiCorp Vault). Require key rotation mechanisms.</p></li><li><p><strong>Destructive Operations:</strong> Any <code>DELETE</code> or <code>DROP</code> operations must implement soft-delete (boolean flags) or robust undo mechanisms. All destructive actions require an immutable audit log entry (actor, timestamp, action, resource).</p></li><li><p><strong>API Contracts:</strong> Endpoints must have defined input/output schemas (e.g., OpenAPI/Swagger) to prevent injection and enforce strict payload boundaries.</p></li></ul><h3>Module 5: Resilience &amp; Traffic Management</h3><ul><li><p><strong>Domain:</strong> System stability under load and failure conditions.</p></li><li><p><strong>Execution Independence:</strong> Can evaluate network and service-layer code.</p></li></ul><ul><li><p><strong>Error Handling:</strong> Implementation of <code>try/catch</code> on all asynchronous operations. Downstream service calls must implement the Circuit Breaker pattern to prevent cascading failures.</p></li><li><p><strong>Rate Limiting:</strong> Ingress traffic must be rate-limited by IP or API key. Outbound retry logic must implement exponential backoff with jitter to prevent thundering herd problems.</p></li></ul><h3>Module 6: Telemetry &amp; Monitoring</h3><ul><li><p><strong>Domain:</strong> Observability, health tracking, and incident alerting.</p></li><li><p><strong>Execution Independence:</strong> Can verify infrastructure-as-code and application middleware.</p></li></ul><ul><li><p><strong>Observability (Logs, Metrics, Traces):</strong> Structured JSON logging must be enforced. Spans and traces must follow requests across system boundaries (e.g., OpenTelemetry).</p></li><li><p><strong>Monitoring &amp; Alerting:</strong> Integration with APM tools. Endpoints must include a <code>/health</code> or <code>/live</code> route checking DB connectivity and memory usage. Usage analytics must be tracked without logging PII.</p></li></ul><h3>Module 7: Verification &amp; Delivery</h3><ul><li><p><strong>Domain:</strong> Automated testing and deployment.</p></li><li><p><strong>Execution Independence:</strong> Runs post-build, parallelized across test runners.</p></li></ul><ul><li><p><strong>Test Coverage:</strong> Strict 100% code coverage requirement across three layers:</p><ul><li><p><em>Unit Tests:</em> Isolated logic, mocked dependencies.</p></li><li><p><em>Integration Tests:</em> Cross-module and database interactions.</p></li><li><p><em>E2E Tests:</em> Full user journey simulation.</p></li></ul></li><li><p><strong>CI/CD Pipeline:</strong> Automated pipelines (e.g., GitHub Actions) must execute linting, type-checking, and testing. Merges to <code>main</code> require automated semantic release creation and deployment script execution.</p></li></ul><h3>Module 8: Documentation Context</h3><ul><li><p><strong>Domain:</strong> Knowledge transfer and operational guides.</p></li><li><p><strong>Execution Independence:</strong> Runs asynchronously, reviewing code to update docs.</p></li></ul><ul><li><p><strong>API Documentation:</strong> Auto-generated from code annotations or strict Markdown.</p></li><li><p><strong>Operational Guides:</strong> Must include a deployment guide, security considerations matrix, and a <code>CONTRIBUTING.md</code> outlining local setup and PR standards.</p></li></ul><p></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[What To Know in JavaScript]]></title>
      <link>https://dustin.boston/blog/what-to-know-in-javascript</link>
      <guid isPermaLink="true">https://dustin.boston/blog/what-to-know-in-javascript</guid>
      <pubDate>Thu, 09 Apr 2026 10:08:00 GMT</pubDate>
      <description><![CDATA[What To Know in JavaScript (2026 Edition) is a great writeup of the JavaScript ecosystem as of April 2026. And also, now I have a ton of new things to learn. ...]]></description>
      <content:encoded><![CDATA[<p><a href="https://frontendmasters.com/blog/what-to-know-in-javascript-2026-edition/">What To Know in JavaScript (2026 Edition)</a> is a great writeup of the JavaScript ecosystem as of April 2026. And also, now I have a ton of new things to learn. </p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Human in the loop]]></title>
      <link>https://dustin.boston/blog/human-in-the-loop</link>
      <guid isPermaLink="true">https://dustin.boston/blog/human-in-the-loop</guid>
      <pubDate>Tue, 31 Mar 2026 06:46:00 GMT</pubDate>
      <description><![CDATA[The current narrative around AI in tech misses a fundamental reality: humans have biological limits....]]></description>
      <content:encoded><![CDATA[<p>The current narrative around AI in tech misses a fundamental reality: humans have biological limits. Big tech pushes the ideal that AI will mint "10x engineers" by drastically increasing throughput. While AI undeniably accelerates workflows, attempting to match that artificial pace with human output is a guaranteed recipe for burnout within six months. There is a physical ceiling to how fast we can type and how much cognitive load we can process at once. AI presents an opportunity to reduce our workload and free up mental bandwidth. Instead, the industry is using it to strap developers to ever-increasing responsibilities. When the system eventually breaks under this pressure, it will be the human in the loop that gives out.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Coding Font]]></title>
      <link>https://dustin.boston/blog/coding-font</link>
      <guid isPermaLink="true">https://dustin.boston/blog/coding-font</guid>
      <pubDate>Mon, 30 Mar 2026 09:25:00 GMT</pubDate>
      <description><![CDATA[Coding Font is a fun bracket game that you can use to find your favorite coding font. I got JetBrains Mono. I think it has a lot of character, and the ligatures are great....]]></description>
      <content:encoded><![CDATA[<p><a href="https://www.codingfont.com/">Coding Font</a> is a fun bracket game that you can use to find your favorite coding font. I got JetBrains Mono. I think it has a lot of character, and the ligatures are great.</p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA["Nothing" is the secret to structuring your work]]></title>
      <link>https://dustin.boston/blog/nothing-is-the-secret-to-structuring-your-work</link>
      <guid isPermaLink="true">https://dustin.boston/blog/nothing-is-the-secret-to-structuring-your-work</guid>
      <pubDate>Wed, 25 Mar 2026 07:22:00 GMT</pubDate>
      <description><![CDATA[The next time you begin your workday, try this: clear your work surface completely. Close all browser tabs. Create a fresh page in your notebook. Open only the one file you need....]]></description>
      <content:encoded><![CDATA[<blockquote><p>The next time you begin your workday, try this: clear your work surface completely. Close all browser tabs. Create a fresh page in your notebook. Open only the one file you need.</p></blockquote><p>Source: <a href="https://www.vangemert.dev/blog/nothing">"Nothing" is the secret to structuring your work</a></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[The 52-Minute Developer]]></title>
      <link>https://dustin.boston/blog/the-52-minute-developer</link>
      <guid isPermaLink="true">https://dustin.boston/blog/the-52-minute-developer</guid>
      <pubDate>Wed, 25 Mar 2026 07:11:00 GMT</pubDate>
      <description><![CDATA[You can code only 4 hours per day, but don't worry, you're only using 52 minutes....]]></description>
      <content:encoded><![CDATA[<p><a href="https://newsletter.techworld-with-milan.com/p/you-can-code-only-4-hours-per-day">You can code only 4 hours per day</a>, but don't worry, you're only using 52 minutes.</p><blockquote><ol><li><p><strong>The cognitive ceiling.</strong> Research by Ericsson, Mark, and Newport shows that 3-4 hours is the daily maximum for concentrated effort. Beyond that, diminishing returns.</p></li><li><p><strong>Where developer time actually goes.</strong> Data reveal that the median coding time is 52 minutes/day. Meetings consume 11+ hours per week, pushing peak coding to the afternoons when mornings should be prime.</p></li><li><p><strong>The cost of interruptions.</strong> 23 minutes to recover from one interruption. For programmers, 30-45 minutes to rebuild the full context. A single meeting can destroy an entire afternoon.</p></li><li><p><strong>Flow as a force multiplier.</strong> Csikszentmihalyi’s research: 500% increase in productivity in the flow state. But flow requires 15-25 minutes of uninterrupted time just to begin.</p></li></ol></blockquote><p></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
    <item>
      <title><![CDATA[Anant Jain on Agency]]></title>
      <link>https://dustin.boston/blog/anant-jain-on-agency</link>
      <guid isPermaLink="true">https://dustin.boston/blog/anant-jain-on-agency</guid>
      <pubDate>Wed, 25 Mar 2026 06:22:00 GMT</pubDate>
      <description><![CDATA[Agency is the ability to hold the entire [development] loop in your head and act on it......]]></description>
      <content:encoded><![CDATA[<blockquote><p>Agency is the ability to hold the entire [development] loop in your head and act on it. What does the user actually need? What should this feel like to use? What's the fastest way to build it that isn't embarrassing? How do we know if it worked? A high-agency person can move through that whole sequence without waiting for someone else to hand them the next step.</p></blockquote><p>Source: <a href="https://www.anantjain.xyz/posts/agency?utm_source=tldrnewsletter">Agency</a></p>]]></content:encoded>
      <author><name>Dustin Boston</name></author>
    </item>
  </channel>
</rss>