Monday, November 02, 2026

Building got cheap. Complexity didn't

 

If you've read me before, you know where I stand: most of our job is learning how things work while we keep complexity under control. This post is a concrete example of how I've been designing and building things lately, trying to keep complexity as low as I can and the cost of each solution small. The idea is simple. Every decision that can be postponed gets postponed, until the moment we actually need to build it.

In Turning up the dial I described the workspace where I do this kind of work, and promised to take it apart piece by piece. Consider this the first piece. Everything in this post happened in there, from the skills I used to the task file where the postponed decisions still live. That post was about the system. This one follows a single feature through it, from the first question to the first real users.

The interesting part isn't the idea. It's the flow, the tools, and the list of decisions we didn't take.

Why this matters more now

AI has removed a lot of friction from building. It also helps a bit with understanding code and systems we don't know; I can get a decent map of an unfamiliar repo in a few minutes. But the amount of complexity a team can hold in its head, operate, debug at three in the morning and change without fear is about the same as it was. Maybe a little more with better tools. Not much more.

We are still the bottleneck. Every streaming connection, every subscription model, every cache adds to the basal cost of a system, the part you keep paying whether anyone uses the feature or not. When writing code was slow, that cost hid behind the effort. Now the code appears quickly, and the complexity stays with us.

So the useful question has changed. It's no longer "can we build it?". It's "what's the least we can build to find out if it deserves more?".

The case

We're removing Slack as the place where our platform talks to people. Alarms, the progress of long operations (creating an application, for example) and personal notices go through a small notification service that, until now, delivered everything to Slack. Some colleagues, who joined from another company, don't use Slack at all. When they create an application from our CLI they get "submitted"... and then nothing.

The feature: let people read their notifications from the CLI.

One more piece of context, because it changes how you should read every number below. I don't code full time. Between meetings, people and everything else, development gets maybe 10–15% of my focus on a good day. So when I say something took a day and a half, that's calendar time at my pace, in the gaps. Someone working on this with full focus would have needed a fraction of that.

This is what the whole thing looked like, from the first question to feedback from real users:

The flow: diverge, converge, record, make the change easy, make the easy change, learn in production

Step 1. Diverge, on purpose

I started a Claude Code session with the grilling skill (from Matt Pocock's skills, I keep a copy in my skill-factory repo). It interviews you about a plan, one question at a time, each with options and a recommendation, until nothing important is left implicit. I asked for exactly that format: one question, a few options, I pick or I write my own answer.

25 questions in 21 minutes.

And here's the part I'm not proud of. Claude's first recommendations were the narrow ones: store only operation feedback, address only people. I was the one who widened the scope. "Everything". "Person, team or topic". Then I threw in an analogy ("how does kubectl do it for events?") and the design grew a server-side stream. Twenty minutes later I had a beautiful system on the table: streaming like kubectl get -w, topics people could subscribe to, read state per message plus a watermark, alarm grouping, an unread counter cached in the background, a neutral message format with a new Slack renderer on top.

None of it was unreasonable. With an agent writing most of the code, I could probably have built all of it in a couple of weeks. That's exactly the problem.

I don't think the divergence was a mistake, though. You need to see the whole problem before you can decide what to leave out. The mistake would have been to stop there.

Step 2. Converge, also on purpose

So I switched tools. I asked for two skills together: complexity-review and hamburger-method. My prompt was, more or less, "find which points add a lot of complexity at the start, how we could solve them, and a much simpler approach".

complexity-review is a skill I wrote that checks a design against 30 dimensions of complexity (state, consistency, latency, dependencies, security, lifespan...) and pushes for the simplest option that works. It found eight drivers in my design. What made it useful wasn't the list. It was the shape of each row: the complex thing, a simpler option, and when to add it.

Streaming became polling every three seconds, "until polling load or latency is a measured problem". Grouping got postponed with a number next to it: around 1,300 alerts in four months is about 11 a day, so "add it when one recipient gets more than ~50 a day". Topics would wait "until a real group needs a channel that is not a team". It also gave a rough guess of the ongoing cost: 15–20% of the team's capacity for my design, 3–5% for the simple one. Those are Claude's estimates, not measurements. I didn't need them to be precise. The order of magnitude was enough.

The hamburger method is Gojko Adzic's technique for slicing a feature vertically; my skill is just a way to apply it systematically. You split the feature into the steps it goes through (the layers of the burger), list several options for each layer from "almost nothing" to "the full thing", and then pick one option per layer so that every slice works end to end. Here it was five layers with five options each:

Hamburger: 5 layers by 5 options. Slice 1 in green, options added later in orange


Slice 1 is the green path. Store every message the service already receives in one Postgres table. Show people their own messages and their teams'. Reuse the existing API key plus an identity token. A plain list command in the CLI. No read state at all; if you want recent stuff, use --since. Estimated at 2–3 days.

Claude proposed slice 1 plus three more cards for the next slices. I went further: one card, slice 1 only, "and write down under what conditions we'd fill in each of the initial decisions, if that time ever comes".

That sentence is the heart of this post.

Step 3. Write down the triggers

The ideas from the divergent phase didn't go to the bin. They went to a table in the task: the postponed decision, the design we had already agreed on in case we build it, and the trigger that tells us it's time. By the end of the work the table had sixteen rows. Here are some of them, with what happened next:

Postponed Slice 1 does instead Trigger to build it What happened
Server streaming List only Polling load or latency is a measured problem Waiting
Live follow by polling List only Someone needs to watch messages live Fired on day 2
Identity-only route API key + identity token The shared key must stop reaching clients Fired on day 3
Read state (one watermark per person) None, filter with --since Daily use makes "what's new" hard to see Waiting
Alarm grouping One row per delivery One recipient gets > ~50 a day (measured then: ~11) Waiting
Topics Unrouted messages go to the owning team A group needs a channel that isn't a team Waiting
Map GitLab users to directory ids Store the id as it comes, log a warning The warnings show a real gap Gap measured: 107 of 138 GitLab messages go to a bot
Retention (90 days) Keep everything ~1M rows, or before general availability Waiting

Writing this table changed how converging felt. Cutting scope usually feels like losing something. Here nothing was lost: the design was there, agreed and written down, waiting for a reason. It also makes the conversation with yourself (or with your team) much shorter the day someone says "we should add topics". Fine. Has the trigger happened?

Step 4. Make the change easy

Before building the slice, I asked Claude to look at the current architecture of the service and prepare it for the feature, using two more skills: thin-wrappers (wrap each piece of infrastructure behind a small interface in the language of the domain) and hexagonal-architecture. It found five problems. The most telling one: the ports were shaped like Slack. Routing only knew Slack targets. If I had added the inbox on top of that, the inbox would have inherited Slack's concepts forever.

That turned into six preparation steps with no new behaviour: domain ports, the GitLab webhook going through the same path as every other message, a shared Postgres base, migrations. About a day of work.

It's the old Kent Beck line: "for each desired change, make the change easy (warning: this may be hard), then make the easy change". I'll be honest, this is also where the method gets a bit uncomfortable. That day was design work done before the slice existed, which is precisely what the rest of this post tells you to avoid. My take is that it's a different kind of design: it doesn't add capabilities, it removes friction from the next change. But I can see someone arguing the other way.

Step 5. Make the easy change

Then the slice itself, in small safe steps (yes, there's a skill for that too). 35 commits in the service and 7 in the CLI between the 19th and the 21st, every push going through the pipeline to production. The database code went to production inert first, with nothing calling it; then the database declaration; then the wiring; then the recording, live on the morning of the 20th. With mutation testing on the pieces that mattered: 46 mutants on the component that records messages, all killed, and two of them found real gaps before production did.

Slice 1 was storing real messages about 38 hours after the design session, and readable from the CLI that same evening. Inside the 2–3 day estimate, and that's with a small slice of my day. With full focus it would have been hours, not days. I think that's the part that surprised me most: the thin slice is so small that even part-time it reaches production before the week is over.

Step 6. Let production decide what's next

Two triggers fired in the first 72 hours.

The first was live follow. I wanted to watch my notifications while an operation ran, so polling moved from the table into the same task as a second slice. The trigger wasn't a metric; it was a user asking. That user was me. I'm fine with that, but it's worth saying.

The second one was more interesting. For the colleagues without Slack, the CLI couldn't depend on a shared API key they'd never have. That was exactly the trigger we had written: "the shared key must stop reaching clients". Before opening the new route we measured what it would cost to abuse it (every forged token meant one request to the identity provider: 50 fake tokens, 50 requests) and added a limit. The design was already in the table. Building it took a morning, a part-time one.

Then came real users. Seven engineers without Slack created test applications with the CLI open in another terminal, following their notifications. One wrote "all good, it took around 30s for the first message to appear". Another: "within a few seconds". Each run produced about eight messages, addressed to the right person.

And real use found things no design session would have found. With no Slack account, the service fell back to a shared Slack channel, so about 37 of their messages also landed in a place nobody expected. One path stored messages for a username that wasn't a person in our directory, so nobody could ever read them. And 107 of 138 GitLab messages were addressed to a bot. That last one was already a row in the table. Now it has a number.

What I'm less sure about

The feedback came from a guided beta that lasted a couple of days, not from people using this every morning. A week later I have no data showing daily use. The check "you see your messages and nobody else sees them" is proven by the data, not by a second person actually trying. And none of the other triggers have fired. Maybe the slice is enough. Maybe nobody uses it enough to need more. I don't know yet, and I'd rather say it.

I'm also aware that the design ended up simple because I asked for it to be simple, after letting it grow. The skills didn't decide anything. They made it cheap to open the space and then cheap to close it again. The table made closing it feel less like losing.

So

Diverge to see the whole problem. Converge to the thinnest slice that works end to end. Don't throw away what you saw: write each postponed decision next to the trigger that brings it back, with a number measured today if you can. Make the change easy, then make it. And let production tell you which row comes next.

None of this is new. Vertical slicing and the last responsible moment are old ideas. What's new is the pressure. When an agent can turn the whole divergent design into working code by Friday, the discipline to converge is about the only thing between us and a system bigger than we can understand.

Which leaves me with a question: now that building the full version costs almost nothing, how many of the features we ship will be just a divergent phase that nobody bothered to converge?

Saturday, October 10, 2026

Turning up the dial: seeing the forest while working on any tree

First post in a series about how I work at Clarity AI with an AI-native workspace. This one covers the experiment and the way of working; the next ones go deeper into specific pieces.

The forest problem

In April I decided to try to see the whole forest and still work on any tree, in any repo, owned by any team, without giving up on quality or on small, safe, sustainable steps. This post is how that went.

As Head of Engineering and Data Platform at Clarity AI, I have to look at the whole system all the time: dozens of repositories, many teams, data pipelines that depend on other data pipelines. If I only look at one repo, I miss what matters. If I only look at the whole, I lose contact with the code, and with it the ability to judge whether what we’re doing makes sense. The usual way out is a trade-off: you see the forest (meetings, documents, dashboards) and stop touching the trees, or you get into one tree and only hear about the rest secondhand. For years I lived somewhere in between, never comfortably.

See the whole forest… and still work on any tree


The experiment: turning up the dial

Kent Beck described Extreme Programming as taking the practices that already work and turning the dial all the way up. If code reviews are good, review all the time. If testing is good, test all the time.

My experiment has two dials that move together. One is the practices I’ve trusted for years: small safe steps, TDD, trunk-based development, everything versioned, checking changes in the running system instead of stopping at the merge. The other is how much work I delegate to AI agents. What I’ve seen so far is that the second dial can only go as high as the first: delegating more without stronger practices just means breaking things faster. That’s an observation from one person over nearly six months, not something I’ve measured, and the rest of the post is the evidence I have for it, including where it falls short.

Turning up the dial: both dials move together


It started on 16 April 2026 as a git repository just for me, which I called platform-office, with a first commit called “bootstrap platform-office AI-native workspace”. The idea was modest: a place where an agent could find everything it needed, so I could stop re-explaining context in every session. The agents are Claude Code sessions, and the co-author trailers in the commits record which model made each change, and it changed over those months.

The mantra: everything is in the repo

One rule shaped everything else: if it’s not in the repo, it doesn’t exist.

That covers code, tasks, decisions, knowledge, communications with other teams, incidents, recaps, the skills the agents use, the tools those skills call, and even the engineering practices, packaged as skills. The company’s code repositories are not inside; they’re cloned when a task needs them. What I ended up with is a single repository for all the context around the code.

The first commit already had tasks/, decisions/, knowledge/ and five skills to manage them. Today it holds hundreds of tasks, decision records and knowledge documents, plus tracked communications, incidents and 45 skills, all plain Markdown with YAML front matter, readable by a person and parseable by an agent.

Everything goes in the repo, and the repo grows

Writing all of that down is what lets an agent pick up any thread from a five-word prompt, and a colleague pick it up without asking me.

Keeping it that way meant going against the defaults. Agent harnesses like Claude Code (the program that runs the agent and enforces its permissions and hooks) save what the agent learns as personal memory, one user at a time. I wanted that knowledge to belong to the team and to anyone using the repo, so I had to be explicit: in August the agents were told to write what they learn into files in the repo, and a check blocks the commit if an instruction file points to private memory. On 10 September I moved the last personal memories worth keeping into the repo. A week later a colleague committed a piece of knowledge with the message “out of one laptop’s memory”.

One system: everything in the repo


How the work gets done: the skill families

A skill, as I use it here, is a flow with phases and gates (points where it stops and waits for a human decision), backed by deterministic tools in the same repo. There are 45, and they cluster into a few families: orienting the agent in the current state of the work, driving a task from capture to close, operations and incidents, the data platform, knowledge and decisions, cross-team communications, code quality, and setup and housekeeping. Several come from the practice skills I wrote about in Encoding Experience into AI Skills.

In practice, a session starts with a short sentence. Some kick off a flow: “run task X”, “look at this alert”, “let’s do a recap of what happened this week”. Others are open questions: “explain how system X works”, “let’s look at how we could improve the architecture of Y”. Either way, the agent loads the context it needs from the repo. It also looks up our organization inventory (more on it below) to find the code repositories related to the request, and clones them when it needs to read the code to give a better answer. Then it keeps working until it needs a decision from me.

Three of them are worth describing in more detail.

The task skill, po-do-task, runs a task through 14 phases and stops for a human decision only where it matters: before implementing, committing, pushing or talking to another team. The phases are: identify, take ownership, clarify, propose alternatives, implement with TDD, mutation testing, test desiderata, report, commit, push, watch CI, validate in the running system, close, and a mandatory postmortem, where the agent reviews what went wrong in the run and proposes changes to the skill itself. Those changes go back into the skill, which several people have rewritten many times.

The incident skill takes a single trigger (a Slack link, a failing pipeline, a pasted alert) through hypotheses and validation, works back from the immediate cause to the systemic one, and ends with follow-up tasks and a postmortem.

The summary skills look at a window of time instead of a single alarm. A census of the Kubernetes event stream complements alerting: it looks for steady signals that never cross a threshold, and proposes which ones deserve a closer look. A weekly health check runs five sources in parallel and crosses them. The manual sweep behind it found its best signal in that crossing: Airflow DAG issues clustering in the same afternoon window as memory pressure in a heavy batch process, which neither source showed on its own.

The principles, in practice

Looking back, the principles I wanted to follow show up in the commits.

See the forest

One repo holds the context of the whole platform, and the code repos a task needs are a command away. It didn’t start that way: I began with git submodules, and by late June there were dozens of them, copied again into every worktree, and the repo had become slow and heavy. On 12 July a decision record replaced them with plain clones on demand.

One code repository is the exception: our organization inventory, present in every session. It’s where Clarity keeps its governance data: dozens of teams and the repositories, Airflow DAGs, container images, Kubernetes deployments, S3 buckets, runtime applications and models each one owns, kept up to date automatically. The workspace reads it instead of copying it. So the first questions of any investigation are cheap: which repositories, applications and data pipelines relate to this topic, and which teams work on it. Even the catalogue of repos and the list of people who can own a task come from there.

Work on any tree

A task registered here is ours to finish, even when the fix lives in another team’s repository. The default is to diagnose the root cause, make the change and coordinate with the owners, with a tracked communication so they’re never surprised, rather than to open a ticket for them. The workspace brings the context; each repository keeps its own rules. A change in someone else’s repo follows that repo’s conventions, CI, review process and owners, in the same small steps as everything else.

Small, safe, sustainable steps

Two weeks in, the pre-commit hook was already running the whole test suite, and the workspace’s own tooling was being hardened with mutation testing. Everything goes trunk-based. Some things stay deliberately slow: any destructive change to live infrastructure is run by a person, one command at a time. The agent writes the exact command; a human runs it and reads the output.

Agents have no access of their own. They work with the access of whoever starts the session, and the rules every session loads keep the important steps in human hands: nothing is pushed, or sent to Slack or to another team, without an explicit go, and when someone approves a specific command, that exact command is what runs.

Experimentation and impact

From the first commit, every task declares its why and can be framed as a hypothesis. In May a validating state appeared: a merged change stays open until it’s checked in the running system. In August came discarded, because a well-argued “we’re not doing this” is also a result; 128 tasks have been discarded on purpose so far.

Learning

Corrections become rules or tools, and sometimes the right call is neither. In July I swept the agent sessions for repeated frictions and the conclusion was clear: rules that live only in documentation get violated; rules enforced by the harness, through hooks and checks, get followed. So corrections keep moving from text into checks, as the next section shows.

When the system got it wrong

Few of the failures I found were an agent doing something silly. Most were the system breaking in ways I hadn’t designed for, and more often than not it was the agent itself, in the mandatory postmortem, who noticed. Three patterns keep coming back.

Rules written as text get ignored; rules turned into tools get followed. A rule that said “use this fallback, the coverage plugin isn’t installed” was ignored in three separate tasks, with the rule in context every time. The postmortem concluded that a rule which has failed three times as prose becomes a make target. The same thing happened with links left behind when a task file moves: the skill first got a paragraph with a workaround, and then the task tool learned to repoint the links itself. When an instruction keeps failing, I stopped writing a better paragraph and changed the mechanism.

The system also has to check itself, including its own checks. One postmortem wrote its lessons into the wrong checkout and then said they were in the commit. Nothing contradicted it, because the working tree looked clean. Now it has to confirm that each lesson’s file shows up in the right git status. Mutation testing reported kill counts that were fake, because tests that crashed were counted as kills. A green pytest line turned out not to be the gate’s verdict. And when a postmortem proposed two more rules for a single friction, it rejected them, with the reason written down: a skill that grows on every friction stops being read.

Then there are the checks that weren’t what they looked like. A shortcut that was safe when someone wrote it stopped being safe once things around it changed. A check ran on every change and still stopped nothing, because nothing was wired to listen to it. A guard added to a shared tool was bypassed by skills that called the tool directly. In each case the check existed and was documented, but it relied on an assumption that was no longer true.

Each time a failure moved from a paragraph into a mechanism, I could delegate a bit more.

From a repo for me to a repo others use

In April, other people made 1% of the commits. In May it was 18%, and in August 46%, with ten people besides me contributing that month. Thirteen people have committed so far. Use keeps spreading, slowly, to other teams and individuals, although most of the commits still come from a few of us.


From a repo for me to a repo others use


What surprised me is that nobody came to “use Eduardo’s tools”. They came with their own problem: running our data pipelines, Snowflake operations, migrating services between platforms, alert noise per squad. The repo gave them context and a mechanism, and several of them then started improving the system: seven of the 45 skills were written by someone else, and one colleague launched an initiative to make the workspace’s context cheaper for every session.

None of them adopted the whole thing, and none of them had to. You don’t need to file tasks, record decisions or run the 14-phase flow to get value from the repo. The pieces are useful on their own and they compose: you can start by reading the knowledge base, pick up one skill weeks later, and register a task or a communication only when it helps. I suspect that’s a big part of why adoption happened without a mandate.

For people who are new to the repo, those open questions are usually the way in. With the context of the whole platform in one place, anyone can open a session and say “this is my situation, I want to do this, how is it done at Clarity?”, and get an answer grounded in our decisions, runbooks and code. A colleague who started using it recently told me it had given him more onboarding than any person had. That kind of use leaves almost no trace in git, so the charts undercount it.

The first time the tooling broke because I wasn’t its only user came in June, when two of us created different decision records with the same number, three times in a week. Sequential IDs assume a single author. Random suffixes on every ID fixed it: a small change, but one you only make when the tool has to work for more than one person.

Then I stepped away. Between 20 August and 1 September I made zero commits, and the repo got 191 commits from six other people.

The system kept moving while I was away

On 6 September we recorded what was already true: the workspace is open to anyone at Clarity, and nobody has to go through me to use it or change it. I steward it: I maintain the tooling, review what lands on main and run the nightly loops. The deeper changes of direction still tend to come from me, mostly because that’s the easy path, not because anyone has to ask.

What I haven’t solved yet

Two problems grow at the same pace as adoption, and I don’t have good answers for either yet.

Integration with the company’s task system

The repo is the source of truth for our work, but the company runs on Jira, and keeping the two in sync is manual: a task here, its mirror ticket there, keys copied by hand. Many commits cite a Jira key in the subject line alone, and some exist only to say “mirror ticket created” or “comment posted”. One housekeeping skill exists only to stop GitLab from turning our DR-NNN and INC-NNN references into links to Jira tickets that don’t exist. I haven’t decided which direction the sync should go, or how to avoid double bookkeeping without breaking “everything is in the repo”. I’m running a few experiments on exactly that right now.

Pruning, cleaning and compacting the knowledge base

“Everything in the repo” also means everything accumulates. Since April, 602 knowledge documents have been added and 30 deleted, with a single explicit cleanup in July. The instruction file every agent session loads grew from about 430 words to about 4,600. Disk space is the least of it: every session spends part of its context on what nobody has pruned, and outdated knowledge is worse than missing knowledge, because an agent treats it as true. My idea is a weekly routine, like the health check, that detects duplicates, stale documents and contradictions with the code or with newer decisions, and proposes the compaction as a reviewable change. The agent proposes, a human decides. It’s not automated yet.

What I’m not claiming

Commits are activity, not value, and many are the workspace’s own bookkeeping. This is not a controlled experiment: one person driving it, better models arriving during the same months, people who were already hands-on. I haven’t compared the workflow against a small guide alone, so I can’t tell how much of the result is the system and how much is the model doing well by itself. The 191 commits from six people in the 13 days I made none tell me the repo works without me. They don’t tell me people would use it if I weren’t the one asking. Writing everything down has a real cost I feel but haven’t measured. And none of this is autonomous: a human approves every push and runs every destructive change, on purpose.

What I can say is how it feels from the inside. The feedback from the people using it has been very good, and I’ve never been this productive, above all on cross-cutting problems, the ones that touch many teams and repos at once and usually stall. That’s an impression, not a measurement, but it’s a strong one.

What comes next

In the next posts I’ll take apart some of the skill families and some of the subsystems behind them, like communications and task management. I’ll pick the order as I go.

And if you lead a platform or engineering team: which of these problems are you fighting right now?


All numbers come from the platform-office git history, from 16 April to 27 September 2026; the failure examples run to early October.

Saturday, September 26, 2026

Good talks/podcasts (Sep II)

These are the best podcasts/talks I've seen/listened to recently:
  • The OKR TRAP Most Companies Fall Into 🔗 talk notes (Dan North) [Company Culture, Management, Strategy, leadership] [Duration: 00:08] (⭐⭐⭐⭐⭐) Dan North traces OKRs back to Drucker's management by objectives and to Andy Grove's rework of them at Intel, then shows the three places organizations break them: defining objectives as activities, tracking work done instead of distance to the goal, and scoring key results at the end of the quarter as if they had been targets.
  • 34. Pensar en sistemas - Donella Meadows - Libros en 20 minutos 🔗 talk notes (Andrés Aguilar, Donella Meadows) [Mental models, Strategy, Systems Thinking] [Duration: 00:21] (⭐⭐⭐⭐⭐) Recorrido por Pensar en sistemas, el libro póstumo de Donella Meadows: qué es un sistema, cómo los bucles de refuerzo y de equilibrio con sus demoras producen comportamientos que nadie quiso, y por qué los puntos de apalancamiento que de verdad cambian algo son los menos obvios.
  • The CTO's Guide to Fixing Slow Delivery 🔗 talk notes (Dave Farley) [Continuous Delivery, Feedback cycles, Management, Nature of Software Development, Small Safe Steps (3s)] [Duration: 00:13] (⭐⭐⭐⭐⭐) Every obvious lever a technology leader reaches for when delivery feels slow — more people, more pressure, more checkpoints — tends to make it slower, because software development is discovery rather than production. Dave Farley makes the case for optimising the speed of learning instead, and letting delivery speed fall out of it.
  • Residues: Time, Change & Uncertainty in Software Architecture 🔗 talk notes (Barry M. O'Reilly) [Architecture, Evolutionary Architecture, Mental models, Resilience, Systems Thinking] [Duration: 00:46] Randomly stressing an architecture produces designs that are more likely to survive events nobody predicted than requirements engineering or risk management manage. Barry M. O'Reilly explains why through complexity science — Kauffman networks, attractors and criticality — and walks through the stressor analysis, the incidence matrix and the PhD experiment built to falsify the whole thing.
  • Building Software That Survives 🔗 talk notes (Michael T. Nygard, Charles Humble) [Architecture, Engineering Culture, Legacy code, leadership, team topologies] [Duration: 00:38] From the 3 a.m. outages that produced Release It to running architecture enablement at Nubank, Michael T. Nygard talks with Charles Humble about autonomy as something you grant per activity rather than wholesale, about Conway's law being a law about communication and not org charts, and about how much a leader changes by what they celebrate rather than by reorganising.
  • Product Thinking on Data and Platform Teams: Is It Worth It? 🔗 talk notes (Jacqueline Lee) [Data Engineering, Legacy code, Observability, Platform engineering, Product] [Duration: 00:41] Product thinking was built for external customers, and porting it to internal data and platform work breaks in specific ways. Jacqueline Lee contrasts a greenfield bank for underbanked Canadians with getting 37 teams off a legacy table at Yelp, and lands on a developer-friendly definition: understanding the user, the business and the tech, and writing code that lets you test, learn and adapt fast.
  • Thinking in Product Outcomes | The Shift Every Engineer Needs to Make 🔗 talk notes (Peppe Silletti) [Feedback cycles, Lean Product Management, Mental models, Product, Product Engineer] [Duration: 00:25] Business outcomes are lagging indicators an engineering team cannot move directly; product outcomes are leading indicators tied to user behaviour that it can. Peppe Silletti works through the difference, the four tests of a good product outcome, and what an engineer can actually do to stop taking orders — with the key concepts mirrored in engineering analogies.
  • The creator of OpenClaw: "I ship code I don't read" 🔗 talk notes (Peter Steinberger, Gergely Orosz) [AI Assisted Engineering, Developer Productivity, Engineering Career, Generative AI, Technical Practices] [Duration: 01:54] Peter Steinberger spent thirteen years building PSPDFKit, burned out, sold his shares and disappeared for three years — then came back straight into Claude Code having missed the years everyone spent deciding AI was useless. He explains to Gergely Orosz why he no longer reads most of the code he ships, why closing the loop is the whole secret, and why he now calls pull requests prompt requests.
  • Beyond the Warehouse: Why BigQuery Alone Won't Solve Your Data Problems 🔗 talk notes (Sarah Usher) [Architecture, Big Data, Cloud, Data Engineering, Software Design] [Duration: 00:44] Scale-ups buy the idea that one tool can do everything and make the warehouse that tool, which works beautifully until latency forces the first team to bypass it — and then everyone copies that bypass. Sarah Usher redraws the architecture around a raw / curated / use case lifecycle, argues that a single source of truth is a place you design rather than a system you own, and makes one request she repeats twice: store your raw data.
  • B2B Startup Metrics | Startup School 🔗 talk notes (Tom Blomfield) [Business models, Lean Startup, Management, Product, startup] [Duration: 00:23] Launching without metrics is flying an aircraft with no instruments, but a dashboard of 500 metrics at a few thousand users is just as useless. Tom Blomfield picks the handful that matter for a B2B startup — revenue, burn, runway, then retention, net dollar retention and gross margin — and explains what each one hides when you get it wrong.
  • How To Start A Dev Tools Company | Startup School 🔗 talk notes (Nicolas Dessaigne) [Business models, Devex, Management, Product Strategy, startup] [Duration: 00:32] Algolia's co-founder, now a YC group partner, walks through the whole arc of a developer tools company: why runtime ideas beat build-time ones, why you almost certainly do not need a business co-founder, when open source is mandatory rather than optional, and why at a dev tools company the documentation, the support queue and the marketing should all be done by engineers.
  • Starting A Company? The Key Terms You Should Know | Startup School 🔗 talk notes (Dalton Caldwell) [Business models, General, Management, startup] [Duration: 00:17] A plain-language glossary of the vocabulary founders are expected to already know — MVP, venture capital, angel, burn rate, seed and series rounds, product market fit, bootstrapping, SAFEs and convertible notes, equity, TAM, valuation, IPO and ARR — with the caveats that matter more than the definitions.
Reminder: All of these talks are interesting, even just listening to them.

You can explore all my recommended talks and podcasts on the interactive picks site, where you can filter by topic, speaker, and rating: Related:

Sunday, September 20, 2026

Good talks/podcasts (Sep I)

These are the best podcasts/talks I've seen/listened to recently:
  • Susanne Kaiser on DDD, Wardley Mapping, & Team Topologies 🔗 talk notes (Susanne Kaiser) [Architecture, DDD, Flow, Strategy, Team Topologies, Wardley maps] [Duration: 00:33] Susanne Kaiser details a holistic framework for designing adaptive socio-technical systems by integrating Wardley Mapping, Domain-Driven Design, and Team Topologies to optimize for a fast flow of change — aligning business strategy with architecture while managing team cognitive load and delivering continuous value.
  • Is Your AI assisted Coding Strategy Quietly Backfiring? 🔗 talk notes (Antony Marcano) [AI Assisted Engineering, Agile, Devops, Flow, Performance, WIP] [Duration: 00:11] Antony Marcano examines how AI-assisted coding acts as a performance magnifier that can inadvertently increase work-in-process and expose systemic bottlenecks in software delivery — with practical guidance on using DORA metrics and flow optimization so AI-driven code generation results in genuine organizational throughput.
  • Save HOURS Of Work & Automate Your AI Agent's Feedback Loop (Do This) 🔗 talk notes (Dave Farley) [AI Assisted Engineering, Continuous Delivery, Developer Productivity, Feedback cycles, Quality, Technical Practices] [Duration: 00:13] Dave Farley shows how meta-automation leverages AI agents to create deterministic feedback tools and custom linting rules, replacing unreliable 'markdown prayers' with automated loops — enabling teams of any size to scale advanced engineering practices and maintain project consistency across different AI models.
  • A Conversation with Amazon CTO Werner Vogels 🔗 talk notes (Werner Vogels) [Architecture, Business models, Cloud, Engineering Culture, Evolutionary Architecture, Programming language] [Duration: 00:48] Amazon CTO Werner Vogels details the principles of 'frugal architecture', offering a pragmatic framework for aligning technical costs with business value and revenue growth — with insights on building sustainable, evolvable systems while navigating the trade-offs of technical debt and reliability at high scale.
  • Software engineering with LLMs in 2025: reality check 🔗 talk notes (Gergely Orosz) [AI, AI Assisted Engineering, Developer Productivity, Engineering Culture, Generative AI, Nature of Software Development] [Duration: 00:25] Gergely Orosz cuts through the executive hype to give a grounded 'reality check' on how engineers across AI startups, Big Tech, and independent work actually use LLMs in 2025 — finding a genuine but nuanced shift, and arguing the right response is to experiment more and learn what has become cheap versus expensive.
  • Turing Award Winner: Data Abstraction, Dijkstra, Distributed Systems | Barbara Liskov 🔗 talk notes (Barbara Liskov) [Architecture patterns, Diversity, Engineering Career, OOP, Programming language, Software Design] [Duration: 00:34] Turing Award winner Barbara Liskov offers a profound look into the creation of modern software engineering, detailing how her pioneering work on data abstraction and distributed systems solved the 1970s 'software crisis' — with lessons on building reliable systems through strict encapsulation and modularity, and a career philosophy of solving fundamental problems rather than incremental ones.
  • Augmented Coding: Mapping the Uncharted Territory 🔗 talk notes (Lada Kesseler) [AI, AI Assisted Engineering, Developer Productivity, Generative AI, Mental models, Technical Practices] [Duration: 02:34] (⭐⭐⭐⭐⭐) Lada Kesseler offers a practical framework for mastering AI-assisted coding, turning unpredictable LLMs into reliable, structured partners through patterns like knowledge checkpoints and specialist agents — with actionable strategies for managing context and non-determinism so developers harness AI's creative breadth without sacrificing technical precision.
  • Marty Cagan on the Current "Golden Era" for Product Management (Full Interview) 🔗 talk notes (Marty Cagan) [AI, Agile, Generative AI, Product, Product Discovery, Product Strategy] [Duration: 01:01] (⭐⭐⭐⭐⭐) Marty Cagan explores the disruptive impact of AI on product management, arguing for a shift from project-driven output to strategic, outcome-oriented discovery and 'building to learn' — while stressing the indispensable role of human judgment and 'product sense' in achieving business viability.
Reminder: All of these talks are interesting, even just listening to them.

You can explore all my recommended talks and podcasts on the interactive picks site, where you can filter by topic, speaker, and rating: Related:

Tuesday, September 08, 2026

El ebook ya está en Leanpub

Hace unos días dije que en breve el ebook estaría en Leanpub. Ya está: https://leanpub.com/menos-software-mas-impacto

Compras una vez y te llevas el EPUB y el PDF, sin DRM. El PDF es lo que no te da el Kindle, y en un libro con diagramas y tablas se agradece.

El precio son 14,99 dólares, con el IVA aparte, porque Leanpub vende en dólares. La ficha deja pagar más si alguien quiere aportar algo más porque considera que le aportalo que escribo y comparto.

Lo digo porque en Leanpub hay muchos libros en curso y este no lo es. Está terminado y cerrado.

Si ya lo tienes en Kindle o en papel, no hagas nada. Esto es para quien no quería pasar por Amazon, o quería el PDF para leerlo en el ordenador y subrayarlo en la tablet.

Te cuento la parte que me toca, porque si no parece que cambio de tienda por capricho: en Leanpub me queda bastante más por copia que en Kindle, sin que tú pagues más. El papel solo está en Amazon y ahí seguirá, así que no te voy a pedir que dejes de comprar allí. Pero si te da igual dónde, ya lo sabes.

Ebook descargable general (pdf, epub), en leanpub: https://leanpub.com/menos-software-mas-impacto

En papel o kindle, en Amazon:

Lo del precio sigue en pie: si no encaja con lo que se cobra en tu país, o con el momento en el que estás, escríbeme y lo arreglamos. No hace falta que me cuentes nada.

— Eduardo Ferro Aldama
Menos software, más impacto

Wednesday, September 02, 2026

El viernes subo el precio del libro

 

El viernes 4 de septiembre suben los precios de Menos software, más impacto en Amazon: el Kindle pasa de 9,99 € a 12,99 € y la tapa blanda de 19,99 € a 24,99 €.

Lo aviso ahora porque sé que hay gente que lo tiene en la lista de "algún día lo compro". Si es tu caso, hasta el viernes sigue como está. Y si me lees el sábado, tampoco pasa nada: el libro no se va a ningún sitio.

Por qué lo subo, por si te interesa el detalle. Puse el precio de salida a ojo, sin tener ni idea de cómo iba a funcionar un libro técnico en castellano autopublicado. Tres meses y cerca de 400 copias después sé bastante más. Y Amazon ha subido el coste de impresión tres veces desde junio, así que cada copia en papel me deja hoy bastante menos que el día del lanzamiento. Con el precio nuevo el libro se parece más a lo que cuesta cualquier otro libro técnico de este tamaño, y me paga el tiempo que le sigo echando: los recursos de la web, las correcciones que me van llegando.

Hay algo que me importa más que el número. Lo pongo mirando lo que se cobra en el sector aquí, y eso no vale para todo el mundo: hay países y hay momentos de carrera en los que 25 € significan otra cosa completamente distinta. Si es tu caso y quieres leer el libro, escríbeme y buscamos cómo. Lo que quiero es que acabe en manos de quien le vaya a servir, y el precio no debería ser lo que lo impida. No hace falta que me cuentes nada.

Esa misma semana hay otro cambio: el Kindle sale de Kindle Unlimited. Si lo tenías apuntado para leerlo con la suscripción, estos días son los últimos.

Si lo quieres antes del viernes:

Y gracias a toda la gente que lo ha leído y se ha tomado el rato de escribirme para contarme qué le ha servido y qué no. Esa parte no me la esperaba y es la que más me está gustando de todo esto.

— Eduardo Ferro Aldama
Menos software, más impacto