<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Walter Gugenberger</title><description>Practical notes on distributed systems, AI-assisted development, and career engineering.</description><link>https://waltergugenberger.com/</link><item><title>Building Marquis</title><link>https://waltergugenberger.com/blog/building-marquis/</link><guid isPermaLink="true">https://waltergugenberger.com/blog/building-marquis/</guid><description>My wife&apos;s PR firm tracked media coverage in a spreadsheet. I asked if they wanted something better. Two months later, Marquis went live.</description><pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every time The Lafayette Company earned a piece of media coverage, someone pasted the link into Slack, then into a spreadsheet. That was the whole system.&lt;/p&gt;
&lt;p&gt;The spreadsheet was a log, not a picture. No way to tell if sentiment was shifting, no view across sources they hadn&apos;t found yet, just whatever ended up in a cell.&lt;/p&gt;
&lt;p&gt;My wife founded The Lafayette Company in 2015. Eleven years in, she&apos;s built it into a seven-person PR firm in Alexandria. I handle their IT, which means I&apos;m in their Slack and I see how the work flows. One evening I asked her whether automated news collection would be useful.&lt;/p&gt;
&lt;p&gt;She said sentiment was the main thing. Not just whether a client got covered, but whether the tone was positive or negative and whether it was moving in a direction they should care about. Beyond that: why were they building reports by hand when a machine could do it. And they were missing coverage from sources that weren&apos;t already landing in Slack.&lt;/p&gt;
&lt;p&gt;They already had media monitoring software. It found clips and filed them. What it couldn&apos;t do was reason about them: tell you whether sentiment was shifting, build a report, or surface coverage from sources the firm hadn&apos;t found yet. The gap wasn&apos;t tooling. It was analysis.&lt;/p&gt;
&lt;p&gt;So I started building.&lt;/p&gt;
&lt;p&gt;Marquis collects from news APIs and RSS feeds across more than 150,000 sources via EventRegistry, Google RSS, and GDELT. It runs on a schedule, scores sentiment from the news APIs, calculates earned media value, and stores everything. When a report is due, it builds one and drops it into Slack and cloud storage. The analysts don&apos;t go looking for it. It shows up.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/diagrams/marquis-workflow.svg&quot; alt=&quot;Marquis workflow: Collect → Analyze → Deliver&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The main interface is Claude. Analysts tell Claude which clients to monitor, what topics to track, how often to run. A Claude plugin handles the setup. When they want to understand what&apos;s happening with a client&apos;s coverage, they ask. Claude fetches the data and talks about it. You can ask why sentiment dropped in a particular week, or how the last month compares to the quarter before, and you get an answer instead of a chart.&lt;/p&gt;
&lt;p&gt;There&apos;s a web interface too. It does much less than you might assume.&lt;/p&gt;
&lt;p&gt;I built the whole thing in about two months of evenings and weekends, most of it written on my phone. If that sounds implausible, I wrote about &lt;a href=&quot;/blog/i-built-a-product-from-my-phone&quot;&gt;how the setup works&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The pilot ran last week. The first automated report came back in a few minutes. The same report would have taken several hours to assemble by hand. The main open issue is cold start latency on low-traffic endpoints. As of this week, the firm is running on it.&lt;/p&gt;
</content:encoded><category>marquis</category><category>ai</category><category>aws</category><category>distributed-systems</category></item><item><title>I built a product from my phone</title><link>https://waltergugenberger.com/blog/i-built-a-product-from-my-phone/</link><guid isPermaLink="true">https://waltergugenberger.com/blog/i-built-a-product-from-my-phone/</guid><description>I built a media intelligence platform for a small PR firm over two months. About three-quarters of it got written on my phone.</description><pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I built a media intelligence platform for The Lafayette Company, my wife&apos;s PR firm in Alexandria, over two months of evenings and weekends. Roughly three-quarters of it got written on my phone.&lt;/p&gt;
&lt;p&gt;The reason I wanted this wasn&apos;t clever. I have a family and real obligations. Finding a clean hour at a laptop is a narrow window on a day like mine, and it almost never lines up with when I actually have ideas. Mostly I had ideas when I wasn&apos;t near a laptop. Waiting for my kid to get ready for soccer practice. Sitting in the pickup line at school. Making coffee.&lt;/p&gt;
&lt;p&gt;It&apos;s the same principle that used to keep work calls tied to a desk phone. You take the Zoom from the car now because the meeting and the afternoon pickup are both non-negotiable, and only one of them can move. Coding just hadn&apos;t caught up yet.&lt;/p&gt;
&lt;p&gt;So I put the agent somewhere the phone could reach it.&lt;/p&gt;
&lt;h2&gt;The setup&lt;/h2&gt;
&lt;p&gt;A small EC2 instance runs a tmux session with Claude Code inside. The Claude iOS app connects over a remote channel. I dictate or type what I want, the agent starts, I close the app.&lt;/p&gt;
&lt;p&gt;Fifteen minutes later. Two hours later. Two days later. I open the app and the session is where I left it — same shell and files, same thought I was mid-sentence on. Whatever the agent got done while I was gone is waiting.&lt;/p&gt;
&lt;p&gt;I&apos;d been watching self-hostable autonomous agents like OpenClaw for a while. The shape was right, but I didn&apos;t want to install one — I work in Claude Code every day. Then Claude Code, randomly, shipped a remote-control function right around when I was thinking about this.&lt;/p&gt;
&lt;h2&gt;The kit&lt;/h2&gt;
&lt;p&gt;The parts aren&apos;t exotic. EC2. Tmux. Claude Code. The Claude iOS app. A small CDK stack to hold it together. The version I run is in &lt;a href=&quot;https://github.com/wuiidl/blog-code&quot;&gt;blog-code&lt;/a&gt;, kept bare — a thing you can fork and have running in an afternoon.&lt;/p&gt;
&lt;p&gt;The setup has limits worth naming. Debugging something complex, reading a long diff carefully, architectural decisions that need multiple files open at once — those still need a laptop. What the phone handles well is direction-setting work: write a spec, kick off a task, review the output, approve the next step. That&apos;s where most of the hours actually went.&lt;/p&gt;
&lt;p&gt;What changes after you do this isn&apos;t the total hours you ship. The hours I spent on this in a typical week weren&apos;t more than before. What did change: the time I already had started to count. Fifteen minutes in a parking lot. The wait before something else. Small stretches that used to be dead time. Over two months of those, I had a product.&lt;/p&gt;
</content:encoded><category>ai</category><category>ai-agents</category><category>devtools</category><category>aws</category><category>mobile</category></item><item><title>Living Specs for AI Agents</title><link>https://waltergugenberger.com/blog/living-specs-for-agents/</link><guid isPermaLink="true">https://waltergugenberger.com/blog/living-specs-for-agents/</guid><description>AI agents forget everything between sessions. One living spec file the agent reads on startup replaces the morning ritual of re-explaining the project.</description><pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every morning when I logged back in, I had to re-educate the AI agent. What are we building, where are we in it, what did we decide yesterday, what&apos;s the convention for this thing and the constraint on that thing and the reason we went with option B instead of A. Ten minutes sometimes, twenty other times. Every single day.&lt;/p&gt;
&lt;p&gt;Multiply that across a week and across a team and it adds up fast. AI agents don&apos;t remember. Every session is day one and that&apos;s not changing any time soon, so the question is what you do about it.&lt;/p&gt;
&lt;p&gt;The answer I landed on is simple. Write it down once, in a place the agent reads on startup, and stop re-typing it. For Claude Code that file is &lt;code&gt;CLAUDE.md&lt;/code&gt;. For Kiro it&apos;s &lt;code&gt;AGENTS.md&lt;/code&gt; or something similar. The name doesn&apos;t matter, what matters is that the agent reads it before it does anything else.&lt;/p&gt;
&lt;p&gt;This isn&apos;t a new idea — &lt;code&gt;.cursorrules&lt;/code&gt;, &lt;code&gt;.aider.conf&lt;/code&gt;, and similar files have been doing something like this for years. What changed is that modern agents are better at actually acting on them, and the cost of keeping them updated is low enough to be worth it.&lt;/p&gt;
&lt;p&gt;So that&apos;s where I put the things I was repeating every morning. The stack, the branches, the conventions, rules like &quot;never push from an agent&quot; and &quot;only commit when I ask.&quot; The stuff a new teammate would want on day one, because that&apos;s exactly what the agent is, a new teammate every single morning.&lt;/p&gt;
&lt;p&gt;Here&apos;s a trimmed example of what one of these files looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# project-name

Web app built with Astro, deployed on Vercel. This file is the
single source of truth for any agent working in this repo. Read
it completely before doing anything else.

## Rules

- DO NOT push code. Ever. Only the human pushes.
- DO NOT commit unless explicitly told to.
- DO NOT merge to `main` without explicit approval. `main` is
  production. Merging is deploying.
- DO NOT start work without a spec. No spec, no code.
- DO NOT invent outside scope. If it&apos;s not in a spec and wasn&apos;t
  explicitly requested, don&apos;t do it.
- DO NOT deviate from specs. If code contradicts a spec, stop
  and flag it.
- DO NOT generate filler. No AI slop, no hedging, no padding.
  If it reads like AI wrote it, rewrite it or flag it.
- DO NOT guess when you can ask.
- Update this file when you learn something durable about the
  project. The next session depends on it.

## Spec-driven workflow

All work is driven by specifications. No exceptions.

- `docs/system-specs/` describes the current state of the project.
  These are living documents. If the system changes, the spec
  changes. If they disagree, one of them is wrong and you fix it.
- `docs/task-specs/` holds one file per piece of work, prefixed
  with the date: `2026-04-15_some-task.md`. Once the task ships
  the spec is frozen. It becomes a historical record of what was
  built and why. Never rewrite a shipped task spec.
- Before starting any work, check for a task spec. If none exists,
  create one first.

## Content workflow

1. Human shares an idea. Agent categorizes it and routes it to
   the content bank or a task spec.
2. When ready, agent creates a dated task spec. Ask probing
   questions to get the real story before writing begins. Don&apos;t
   fill gaps, surface them.
3. Draft on a branch. Never pad. If a section is thin, ask for
   more rather than generating generic content.
4. Review via PR. Every sentence earns its place.
5. Merge only with explicit approval.

## Branches

- `main` is production. What&apos;s in main is live.
- `develop` is the integration branch for ongoing work.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I put one rule at the top of the file: this is a living document. When the agent learns something durable about the project, it updates the file. Next session inherits the knowledge and the tax goes to zero.&lt;/p&gt;
&lt;p&gt;The one discipline this requires: keep it honest. When you skip an update after the project changes, the next session pays for it with confusion. The file is only as useful as the last time someone kept it current.&lt;/p&gt;
&lt;h2&gt;Two kinds of specs&lt;/h2&gt;
&lt;p&gt;Once the entry point was sorted I had to deal with the rest of the docs. I used to have a flat &lt;code&gt;docs/&lt;/code&gt; folder with a pile of specs. Some described the current state of the system and others described a specific piece of work I&apos;d done six months ago. They lived next to each other and drifted apart. That confused me and it definitely confused the agent.&lt;/p&gt;
&lt;p&gt;So I split them. &lt;strong&gt;&lt;code&gt;docs/system-specs/&lt;/code&gt;&lt;/strong&gt; is living documentation that describes what the system is right now. If the system changes, the spec changes. If the spec and the code disagree, one of them is wrong and you fix it. &lt;strong&gt;&lt;code&gt;docs/task-specs/&lt;/code&gt;&lt;/strong&gt; is frozen, one file per piece of work, prefixed with the date: &lt;code&gt;2026-04-15_some-task.md&lt;/code&gt;. Once the task ships the spec becomes a historical record. You don&apos;t rewrite it, it&apos;s the timeline of what got built and why.&lt;/p&gt;
&lt;p&gt;The agent knows which is which because they live in different folders. When I start a new task the agent creates a task spec with today&apos;s date, we iterate on it, and once I approve it implements against the spec. When it&apos;s done the spec stays and a month from now if I want to know why I did something the dated file is right there.&lt;/p&gt;
&lt;h2&gt;It&apos;s not just for code&lt;/h2&gt;
&lt;p&gt;Here&apos;s what I think is the interesting part. None of this is specific to code. This blog you&apos;re reading right now is set up the same way. There&apos;s a &lt;code&gt;CLAUDE.md&lt;/code&gt; that tells the agent how I write and what my content pillars are, a system-specs folder with the content strategy and post conventions, and a task-specs folder with a dated spec for every post including this one. When I sit down to write the agent already knows the voice, it knows the structure, and it knows to ask me for the story before it fills in blanks. I don&apos;t have to explain any of that.&lt;/p&gt;
&lt;p&gt;Any domain where you work with an AI agent over time can use this. Research, consulting, writing a book, running a small business. Anywhere you&apos;d otherwise be explaining the same context over and over.&lt;/p&gt;
&lt;p&gt;I set this up for myself to stop repeating context every morning. But the real payoff showed up when someone else joined the work. They didn&apos;t have to ask me how anything was organized. They opened the repo, their agent read the file, and they were in the work — no orientation, no &quot;how do you have this set up&quot; questions. That&apos;s what happens when you write things down once. The file doesn&apos;t care who opens it, whether that&apos;s a human, an agent, or future-you who forgot.&lt;/p&gt;
&lt;p&gt;If you think about it, this is persistent memory. It&apos;s just file-based. The &lt;code&gt;CLAUDE.md&lt;/code&gt; mutates as the project evolves, the system specs update when the system changes, and the task specs accumulate over time. Some of it stays current and some of it becomes historical context. That&apos;s how memory actually works, it&apos;s just living in your repo instead of in the model.&lt;/p&gt;
&lt;p&gt;Some tools are starting to build this in natively. Claude has a memory feature in the app and in Claude Code. It remembers things about you across conversations. But from my experience it&apos;s still pretty thin, more like sticky notes than real documentation. It captures high-level facts but not the depth of how you actually work on a project day to day.&lt;/p&gt;
&lt;p&gt;The spec structure fills that gap for project-level memory. But there&apos;s still a missing layer above it. The stuff about you that should follow you everywhere regardless of which repo you&apos;re in. How you like to work, how you communicate, your preferences and patterns that aren&apos;t tied to one codebase. That&apos;s personal memory and it&apos;s the piece that&apos;s still not solved well. I&apos;ll write about that next.&lt;/p&gt;
&lt;p&gt;For now, if you&apos;re still re-educating your agent every morning, stop. Write it down once. Let the project do the teaching.&lt;/p&gt;
</content:encoded><category>ai</category><category>spec-driven-dev</category><category>ai-agents</category><category>career</category></item><item><title>One Hour to Save the Data</title><link>https://waltergugenberger.com/blog/one-hour-to-save-the-data/</link><guid isPermaLink="true">https://waltergugenberger.com/blog/one-hour-to-save-the-data/</guid><description>I needed cross-region disaster recovery for DynamoDB. Built a config-driven CDK solution with AI in about an hour. The org adopted it by noon.</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I needed to build a disaster recovery solution. The goal was to get DynamoDB data backed up to a different region on a continuous basis. Not a one-off export. Something reliable that runs on its own.&lt;/p&gt;
&lt;h2&gt;The approach&lt;/h2&gt;
&lt;p&gt;DDB has an export API that allows customers to move data to an S3 bucket which can be in a different region. While we could have run this manually we needed something that was reliable and continuous. At least as much as possible.&lt;/p&gt;
&lt;p&gt;I decided to deploy a lambda that ran at scheduled times. Exports the tables into an S3 bucket. The lambda had to accept a list of tables and a destination. Ideally this solution was repeatable for future applications (which we needed the next day). A config driven approach deployed via a pipeline seemed ideal.&lt;/p&gt;
&lt;h2&gt;Building it&lt;/h2&gt;
&lt;p&gt;I created a CDK project and told Kiro to start a spec. I needed a lambda, S3 bucket, IAM roles and a schedule. Some alarming and monitoring would be nice too, but nothing crazy. Oh yeah, and I needed the inputs (table names, buckets) to be created based on a config. That way the CDK stack can be deployed over and over with different parameters.&lt;/p&gt;
&lt;p&gt;Writing a spec with Kiro is an iterative approach. It starts out, gets things right and some wrong. You read the spec and make corrections. And when you&apos;re happy you tell it to go implement. Then you check the implementation and most of the time it&apos;s good. Sometimes you tweak in a few spots. The spec took a few minutes to write and so did the implementation. A deployment to preprod to make sure the whole thing worked, a review, and out to production. Total time about 1h, maybe 90 min.&lt;/p&gt;
&lt;h2&gt;Built for reuse&lt;/h2&gt;
&lt;p&gt;The config-driven setup meant that pointing it at a different set of tables and buckets was a config change, not a code change. That&apos;s why a second region came together the next day in minutes instead of hours — same stack, different parameters.&lt;/p&gt;
&lt;h2&gt;What I did vs. what the AI did&lt;/h2&gt;
&lt;p&gt;Kiro acted like a personal assistant. It took my thoughts and wrote them into a spec. Organized them (I can be all over the place sometimes), and when I was ready it implemented everything. It confirmed with a successful build.&lt;/p&gt;
&lt;p&gt;Kiro didn&apos;t know we needed cross region replication. It didn&apos;t know the tables we needed to save. And it wouldn&apos;t have known that we want to build this future proof and configuration driven. All that work happened because of the experience of the human operator but a human could not have built something so sophisticated so quickly, or at least this one couldn&apos;t have.&lt;/p&gt;
&lt;h2&gt;One hour&lt;/h2&gt;
&lt;p&gt;With the help of AI I was able to build something quickly and with minimal issues. Generally those two things are in tension. It was successful because of the help of the friendly ghost (Kiro) and the combined experience building applications and knowing the underlying system.&lt;/p&gt;
&lt;p&gt;AI is good at that. And if you know how to use it that&apos;s the difference between having a solution in an hour or still working on it by the end of the week.&lt;/p&gt;
</content:encoded><category>ai</category><category>aws</category><category>spec-driven-dev</category><category>distributed-systems</category><category>career</category></item><item><title>Why This Blog</title><link>https://waltergugenberger.com/blog/why-this-blog/</link><guid isPermaLink="true">https://waltergugenberger.com/blog/why-this-blog/</guid><description>Twelve years of shipping software with nothing public to show for it. A record of what I built, what broke, and what AI changed about how I work.</description><pubDate>Sat, 28 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been a software engineer for 12 years. I just had my work anniversary in early March. I started at a startup, ran my own consulting company, then bootstrapped another one. I&apos;ve worked in large enterprises too. I&apos;ve built a lot of things and I have little to show for it, in terms of artifacts. I can give you a resume but I&apos;ve forgotten more than what&apos;s on that resume.&lt;/p&gt;
&lt;p&gt;I want to start writing this blog to keep a record of what I&apos;ve done and what I am thinking about at the time of writing. It&apos;s not going to be your millionth tutorial on how to set up Claude Code (ok, maybe a little for one specific thing I did). But I want to show what worked for me and what didn&apos;t. If it helps someone, great. If it doesn&apos;t, also great.&lt;/p&gt;
&lt;p&gt;I&apos;m not here to tell you AI is going to change the world or take your job. I don&apos;t know if it will. What I do know is that I&apos;ve been using it to ship real software, and some of it has been genuinely impressive and some of it has been garbage. Like any tool. It&apos;s not magic and it&apos;s not the apocalypse.&lt;/p&gt;
&lt;p&gt;What it is, for me, is practical. My wife founded The Lafayette Company in Alexandria in 2015 and has built it into a seven-person PR firm over the past eleven years. I built Marquis for them: a full production system with DynamoDB, Lambda, EventBridge, Slack integration, the whole stack. I built Gilbert, a Rust CLI that talks to that platform. I coded half of both of them from my phone.&lt;/p&gt;
&lt;h2&gt;The phone thing&lt;/h2&gt;
&lt;p&gt;I have a family. Young kids. Anyone with small children knows the math: if something requires pulling out a laptop, finding a quiet spot, and getting into a flow state for two hours, it&apos;s not getting done. Not on a weeknight. Probably not on a weekend either.&lt;/p&gt;
&lt;p&gt;But I can write a spec on my phone during a lunch break. I can refine it at night after the kids are down. And with spec-driven development, where the spec is the source of truth and the AI implements against it, that&apos;s enough. I write the what and the why. The AI handles the typing.&lt;/p&gt;
&lt;p&gt;I set up Claude Code running remotely on an AWS instance and controlled it from my phone. I&apos;d write a spec, send it over, review what came back, refine, iterate. Marquis and Gilbert got built in the cracks of my day. Ten minutes here, twenty minutes there.&lt;/p&gt;
&lt;h2&gt;What I think about AI, honestly&lt;/h2&gt;
&lt;p&gt;I&apos;m not scared of it. If AI takes my job someday, so be it. Me refusing to learn it won&apos;t slow it down. I&apos;d rather be at the front of this wave than scrambling to catch up when it&apos;s too late.&lt;/p&gt;
&lt;p&gt;But I&apos;m also not a true believer. I&apos;ve seen AI write clean, correct infrastructure code in minutes. I&apos;ve also seen it confidently generate something that would have taken down a production service. The skill isn&apos;t in using the AI. The skill is in knowing what to ask for, knowing how to validate what comes back, and making the design decisions that the AI can&apos;t make for you.&lt;/p&gt;
&lt;p&gt;The developer is still the one in charge. You&apos;re the architect, the decision-maker, the person who says &quot;make this config-driven so other teams can use it.&quot; The AI writes the code. You make the calls.&lt;/p&gt;
&lt;h2&gt;What&apos;s coming&lt;/h2&gt;
&lt;p&gt;I&apos;m going to write about the things I&apos;ve actually built and operated. For now, I am committing to write about these three things (I claim to have expertise in):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI-assisted development in practice&lt;/li&gt;
&lt;li&gt;Distributed systems and cloud architecture&lt;/li&gt;
&lt;li&gt;Career engineering&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I recently built a disaster recovery framework during an operational crisis. A full IaC solution for exporting DynamoDB data to safe regions. Spec-driven, built in one hour, and the entire org adopted it by noon the same day. That&apos;s a story I want to tell. There are more like it.&lt;/p&gt;
&lt;p&gt;There&apos;s one more reason I&apos;m writing this, and it has nothing to do with tech. I know very little about some of the people in my family who came before me. They&apos;re not here to tell their story anymore. I don&apos;t want that to happen to mine. Someday my kids/grand kids might want to know what their papa was building and thinking about during these years. This is that record too.&lt;/p&gt;
</content:encoded><category>ai</category><category>career</category></item></channel></rss>