Showing posts with label personal. Show all posts
Showing posts with label personal. Show all posts

Tuesday, June 23, 2026

Cómo se hizo «Menos software, más impacto»

El libro lleva un par de semanas a la venta y hay una pregunta que me repiten: ¿cuánto se tarda en escribir algo así?

La respuesta honesta es que no lo sé. Y no lo sé porque el libro no empezó siendo un libro. Empezó como una serie de posts, sin ningún plan de acabar en Amazon.

Como esta semana toca contar el proceso, me he puesto a reconstruir las fechas con el historial de git, los nombres de los ficheros de las entrevistas y los registros de los trámites. Esto es el making of, sin maquillaje.

No nació como libro, nació como serie

En abril de 2024 publiqué el primer post: "Introducción al Lean Software Development". No iba a ninguna parte concreta. Escribía sobre lo que había ido aprendiendo en equipos reales, un tema por entrega.

Salieron unos dieciséis posts en unos dieciséis meses. Con su parón y todo: después de "Empoderar al equipo" me quedé sin gasolina y la serie estuvo parada buena parte del invierno de 2024. La retomé en primavera de 2025 con el bloque de calidad (cinco posts casi seguidos) y la cerré en agosto de 2025 con "Lean, XP y mentalidad de producto".

Al principio no pensaba en ningún libro, solo en el siguiente post. Pero hacia la mitad de la serie la idea empezó a rondarme: con todo este contenido, quizá había un libro ahí. La aparqué casi enseguida. Me parecía algo lejano y con demasiado trabajo detrás, una más de las muchas ideas que siempre tengo dando vueltas en la cabeza. Aun así, según avanzaba y veía cuánto material se iba acumulando, la idea se hacía más fuerte. Lo que la frenaba era siempre lo mismo: el trabajo que parecía implicar.

El empujón que me lo hizo creer

Tenía el material, y cada vez tenía más claro que ahí había un libro. Lo que seguía frenándome era imaginar el trabajo por delante. Lo que no esperaba es que el desbloqueo llegara de una conversación que no iba de eso.

No nos conocíamos mucho: había hablado con Juan Macías unas pocas veces (algo por mensajes y un par de videollamadas), por temas que nada tenían que ver con escribir un libro. Juan está innovando de forma bastante radical en el uso de la IA para el desarrollo de producto, y además se había escrito un libro con ayuda de la IA, The Broken Telephone, lleno de ideas que me parecieron muy buenas. Tuvimos varias conversaciones sobre ellas.

Como efecto colateral de esas charlas, le pregunté por el propio proceso de crear el libro. Su forma de plantearlo, muy apoyada en la IA y en automatizar casi todo, me hizo verlo de otra manera: el muro de trabajo que me frenaba, de repente, parecía mucho más bajo. Y Juan fue tan generoso como para pasarme el repositorio base que había usado: los scripts, la estructura, todo el harness. Ese fue mi punto de partida. Me dio una base técnica sobre la que construir, sí, pero sobre todo me dio algo más difícil de conseguir: creerme que hacer el libro en un tiempo razonable era posible.

Sin esa conversación, el libro probablemente seguiría siendo una idea más en mi lista.

De posts a libro: poco más de cuatro meses

El 30 de enero de 2026, sobre esa base, hice el primer commit del repositorio. Ese día empezó "el libro" de verdad.

Aquí viene una de las cosas que más me sorprendió: en un par de días ya tenía la estructura entera, los catorce capítulos iniciales convertidos de posts a esqueleto de libro. Tener la serie escrita lo cambia todo. No partía de una página en blanco, partía de material que ya había pasado por el filtro de publicarlo y recibir respuestas.

Cuatro meses de ensamblaje, commit a commit.
No recoge los 16 meses de escritura de posts.

Lo escribí en un repositorio de git, como si fuera código, y me apoyé en la IA para aumentar mi capacidad: automatizar lo repetitivo, ordenar el material, forzar la crítica sobre mis propios textos. Las ideas, la experiencia y la voz son mías; la IA me ayudó a llegar más lejos y más rápido.

Y, como en casi todo lo que hago, el proceso entero fue un experimento: con sus hipótesis, sus validaciones e invalidaciones, y mucha iteración. Probaba una manera de trabajar, miraba si funcionaba y ajustaba. Buena parte de lo que acabó funcionando no estaba en el plan inicial.

Del primer commit a tener el libro a la venta pasaron poco más de cuatro meses.

El giro: no quería otro manual

A las pocas semanas tuve que parar y decidir qué clase de libro quería que fuera.

Podía salir un manual de Lean correcto. Otro más. Y, sinceramente, ni me apetecía escribirlo ni creo que hiciera mucha falta. Así que cambié el rumbo: si iba a hacerlo, tenía que ser un libro con una tesis propia, aunque incomodara un poco.

La tesis es esta: el mayor problema de los equipos no es que escriban código malo, es que escriben código de más. Todo el software que existe cuesta, lo uses o no, igual que el cuerpo gasta energía solo por estar vivo. Si no gestionas ese coste, crece hasta ahogar la capacidad del equipo. Lo llamo el coste basal del software, y atraviesa el libro de principio a fin.

A partir de ahí dejó de ser "un libro sobre Lean" y pasó a ser un libro sobre algo más incómodo: por qué muchas veces lo más valioso que puedes hacer es construir menos.

Las conversaciones: porque uno solo no lo ve todo

Una tesis como esa no se sostiene solo con mi cabeza. Y hay una parte del proceso que no se ve en los posts: las conversaciones. Diecisiete entrevistas, repartidas en dos oleadas, con gente con la que he trabajado a lo largo de los años.

¿Por qué entrevistar si el libro recoge mi experiencia? Porque por mucho que reflexiones, tú solo no sacas puntos de vista distintos sobre un mismo tema. Te quedas encerrado en tu propia perspectiva. Necesitaba a personas que habían vivido lo mismo desde su sitio y lo contaban con sus palabras, a veces para confirmar lo que yo pensaba y a veces para discutírmelo. Quería que el libro tuviera más miradas que la mía.

La primera oleada arrancó en junio de 2025, cuando todavía publicaba la serie y el repositorio del libro ni existía. La segunda llegó a principios de 2026, ya con el libro en marcha. Muchas de esas voces acabaron dentro del libro. Se estaba cocinando mucho antes de que yo me diera cuenta de que estaba escribiendo un libro.

La parte que nadie cuenta: los papeles

Escribir es la parte bonita. Luego está la otra.

Cuando tuve el contenido cerrado y las imágenes más o menos resueltas, me di cuenta de la cantidad de decisiones que me quedaban por delante y de lo poco preparado que estaba para tomarlas: formato, modelos de distribución, tipos de papel, precios, registro de Propiedad Intelectual, ISBN, márgenes, tipografías, contraste de las imágenes. Todo eso había que decidirlo, y yo no había hecho nada parecido en mi vida.

La portada completa(contra, lomo y cubierta) sobre la plantilla.

Ahí tuve mucha suerte. Pude contar con dos personas que ya habían pasado por esto. Gerard Chiva, que tiene varios libros publicados en Amazon y un nivel de experiencia y de herramientas que es casi el de una editorial propia. Y Carlos Iglesias (de Runroom), autor de Impact-Driven Growth, que acababa de publicar el suyo y lo tenía todo reciente.

Que se prestaran a sentarse conmigo en una videollamada lo cambió todo. En lugar de ir decidiendo a ciegas, pude contrastar cada duda con alguien que ya había pasado por lo mismo antes que yo. Buena parte de los aciertos del libro, los que tienen que ver con cómo está hecho y no con lo que cuenta, salieron de esas dos conversaciones. Sin ellas habría llegado a algo bastante más torpe.

Una prueba del interior, con las marcas de corte.


A la venta

El 6 de junio de 2026 el libro estuvo disponible en Amazon, Kindle y tapa blanda a la vez. Lo anuncié ese día y al siguiente salió en redes.

Antes de publicar me había puesto unos números como objetivo, casi para tener una vara de medir honesta: 200 copias en los primeros seis meses, 300 en el primer año y que al menos el 60% fueran en papel y no en digital. Los escribí sin saber muy bien si eran ambiciosos o ingenuos.

A 22 de junio, dieciséis días después del lanzamiento, van 234 copias. El objetivo de seis meses se cumplió en las dos primeras semanas y ya estamos cerca del de doce. No me lo esperaba, y menos tan rápido. Que casi todo se vendiera en España lo daba por descontado; lo que sí me sorprendió fue el papel: el objetivo de mezcla se ha superado de largo, más del 80% de las copias son físicas.

Unidades por formato a 22 de junio: 185 en papel, 49 en digital.


Una segunda versión, esta misma semana

Y como el proceso no termina el día del lanzamiento: esta semana acabo de subir una nueva versión en papel.

Son cambios menores, todos para que se lea mejor: un margen interior algo más amplio (que el texto no se meta en el lomo), mejora de contraste en unas pocas imágenes y algún retoque suelto de maquetación. El contenido no cambia. Si ya tienes el libro, no te pierdes nada.

Me gusta que se pueda hacer esto. Detectas un detalle, lo corriges y lo subes. Muy en la línea de lo que defiende el propio libro: pasos pequeños, mejorar sobre lo que ya funciona.

Lo que me llevo

Si tuviera que quedarme con una idea del proceso es esta: un libro así no se escribe de una sentada, se cultiva. Dieciséis meses de escribir en abierto, diecisiete conversaciones, más de 180 correcciones llegadas de los revisores y cuatro meses de ensamblaje, con un puñado de personas echando una mano. Visto con perspectiva, el libro fue la consecuencia, no el objetivo.


Nota: durante todo esto fui dejando un rastro bastante completo de cómo lo hice: el flujo de trabajo, las herramientas, las plantillas de exportación, los scripts. Si veis interés, me planteo publicar un pequeño kit de autoedición (o, para quien le tire lo técnico, el tooling concreto que usé para escribir, maquetar y exportar el libro). Si os sería útil, decídmelo en comentarios o contactadme y lo preparo.

Sunday, June 14, 2026

Ya está publicado «Menos software, más impacto»

Después de meses de trabajo, ya está aquí mi primer libro: «Menos software, más impacto».


Va sobre desarrollo de software Lean. Sobre algo que llevo años viendo y que sigue costándonos asumir: muchas veces construir menos, quitar lo que sobra y mirar el impacto de verdad nos lleva más lejos que seguir añadiendo funcionalidad. He volcado ahí buena parte de lo que he aprendido en más de 25 años, con ejemplos de equipos y empresas reales por los que he pasado.

Y estos días están empezando a llegar las primeras copias físicas a sus lectores. Para alguien que se dedica a fabricar algo tan intangible como el software, verlo en papel hace una ilusión rara y bonita.

Lo tienes en tapa blanda y en Kindle (también en Kindle Unlimited): comprar en Amazon.

Monté además una web con los recursos por capítulo, gratis y abiertos, te leas el libro o no: recursos del libro.

Si lo lees y te aporta algo, una reseña honesta en Amazon ayuda muchísimo estas primeras semanas. Y si tienes cualquier comentario, me encantará leerlo.

Sunday, May 10, 2026

El libro está cerca: web de recursos y un Substack dedicado

Después de bastante tiempo trabajando en él, mi libro Menos software, más impacto está cerca de estar terminado. La edición en español está prevista para junio de 2026, y poco después saldrá la edición en inglés.

Mientras tanto, he preparado dos cosas:

Una web con recursos del libro, organizados por capítulos: menos-software.eferro.net. La iré ampliando a medida que el libro avance, con referencias, charlas, artículos y otros materiales que complementan cada capítulo.

Un Substack específico para el libro: menossoftware.substack.com. Lo he creado aparte a propósito, separado de eferro's Substack. La cadencia será muy baja por diseño: solo escribiré allí cuando haya algo concreto sobre el libro (publicación en Amazon, edición en inglés, extractos, errata, segunda edición). Si quieres enterarte cuando salga sin recibir nada más, suscribirte allí es la mejor opción.

Aquí en el blog y en eferro's Substack seguiré escribiendo sobre Lean, XP, construcción de equipos y cómo entregamos mejor software.

Gracias por acompañarme en este camino.

Artículo relacionado: El libro que llevo 25 años intentando escribir — la historia detrás del libro.

Enlaces:

Sunday, April 26, 2026

How I use Claude Code to maintain an Obsidian vault

Seven mental models had been sitting in my inbox for weeks. Rough captures I'd jotted down while reading and watching things online: a stub here, a link there, a sentence I wanted to come back to. I asked the agent to flesh them out into proper notes. It dropped each one in the right folder, got the tags right, updated the central index, and committed the batch with a sensible message. No broken links. All in one session, and I didn't touch a single file.

That sentence is easy to write and easy to misread. It sounds like magic, or like marketing copy, or like the kind of thing people say about AI before you try it yourself and it puts notes in the wrong folder and breaks half the links in your vault. So let me explain what actually made it work, because it wasn't the model. It was the scaffolding.

A previous post described the general system: markdown files on Dropbox, versioned with Git, an AI agent that operates on the vault. This one is about a narrower question the first post barely touched. How do you give an agent durable, specific knowledge of a vault it didn't create, so that it stays consistent across sessions, not just within one?

Rules as the agent's memory

Claude Code reads a set of rule files at the start of every session. They live in .claude/rules/ and load automatically. This is the part most write-ups about "AI plus Obsidian" skip. The rules are not a prompt I rewrite each time, and they're not a long system prompt I crafted once and forgot about. They are operational memory: stuff that persists between sessions and grows the more I use the agent.

The main file, obsidian.md, runs to a few hundred lines. It describes the PARA structure and where each type of content belongs, how wiki-links work, the format conventions for literature notes, evergreen notes, Maps of Content (MOCs), mental models. It also tells the agent which Python script to run in which situation and how to interpret the output. A second file, vault-management.md, is more operational: when to use find_broken_links.py versus fix_broken_links.py, what to do with a fuzzy match at 73% versus 91% confidence. A third, master-viu-presentaciones.md, covers the conventions for the master's program materials I teach.

None of these files is static. After every session where I learn something, I update the relevant one. Sometimes it's a convention I'd been applying inconsistently. Sometimes it's a pattern that worked better than what I had documented. Sometimes it's just a rule I'd been meaning to write down for weeks. The next session starts with that lesson already loaded, and the agent doesn't need to rediscover it.

This is what separates "I told the agent the rules" from "the rules live in the repo and improve with use." Most setups stop at the first. Getting an agent to write a note is trivial. Getting it to write a note that's consistent with 774 other notes it didn't write, and to keep it consistent over months, is what needs this kind of explicit, maintained context.

The zero broken links rule

The single most important rule in the vault is this one: if you're not certain a note exists, don't create the wiki-link. Use plain text instead.

A broken link in Obsidian isn't a 404. It's a ghost. The link renders, it shows up in the graph view, it looks like a connection. But click it and you're in an empty note. Broken links are promises the vault never kept. They make the graph misleading. They accumulate silently, each one suggesting knowledge that isn't there.

The rule is enforced two ways. In the agent's behavior: before writing [[SomeConcept]], Claude Code runs a Glob search to confirm the file exists. If it doesn't, it uses plain text. No exceptions. And in a Python script:

make find-broken-links

This runs after any session that involved creating or editing notes. It parses every .md file in the vault, extracts every [[wiki-link]], and checks that a file with that name exists. The output is a table. The acceptable result is zero.

There's a principle I keep coming back to here: you can't trust an agent's self-reporting on something like link integrity. The agent thinks it checked. The script actually checked. Both have to be in the loop.

The mechanical layer

Behind the agent there are 15 Python scripts wired together through a Makefile. They are the part of the system that doesn't improvise.

find_broken_links.py I've already described. Its companion, fix_broken_links.py, handles the cases where a broken link is a typo or a slightly different name of an existing note. It uses difflib for fuzzy matching, configurable threshold, interactive confirmation by default. --auto-apply --threshold 0.90 handles the obvious cases without asking; --dry-run shows what would change without touching anything. validate_frontmatter.py scans every note and checks that the YAML is valid, that title is present, and that tags is a list rather than a bare string. These drift surprisingly fast during fast note creation, and catching them at the script level keeps them from accumulating into a future cleanup job.

The principle behind the whole layer is the one above: the agent decides, the scripts verify and execute the repeatable mechanics. The agent says "I created seven notes." The script confirms whether the wiki-links between them resolve. Two different jobs, run by two different actors, with no overlap of trust.

The middle layer

Between rules (context for the agent) and scripts (mechanical operations), there is a third layer: skills. These are workflow protocols that combine agent judgment with script execution.

The vault has six. create-note creates a note with the right frontmatter, in the right PARA location, with the right tags. If something's missing it asks before guessing. fix-broken-links runs the detection script, applies the obvious fixes automatically, and surfaces the edge cases for me to decide. vault-health-check runs the full check-health suite and tells me what to fix and in what order.

The distinction I care about is this: a skill is not a prompt. A prompt runs once and the agent improvises the rest. A skill is a protocol. It's explicit about which tools to use, in which order, what to verify, and when to ask the human. The same skill runs the same way every time. That's what you want for maintenance work. Boring, repeatable reliability. Not novelty.



The pattern: friction → script → skill → rule

None of this was designed upfront. It evolved from use, and the evolution is visible in the commit history.

Each piece started as a friction. I'd notice I was making the same judgment call session after session, or hitting the same dull task by hand, or repeating a correction I'd already made. The first response was a script for the mechanical part. Then, when the script was being called the same way each time, a skill that wrapped the orchestration. Then, when the lesson was something the agent should always know, a line in the rules so the next session would start with it loaded.

The presentation materials for the master's program followed exactly this arc. After the third session I noticed I'd made the same mistakes twice: too many bullets per slide, explanatory content in visible slides instead of speaker notes, material that didn't fit the session dumped at the end of the main presentation. I spent an hour updating the rule file with what I'd learned. From session four onward, Claude Code applied those lessons automatically. I didn't have to remember them. The rules remembered them for me.

Every problem I solve ends up encoded in a rule, a script, or a skill. The next time the same problem turns up, the agent already knows the answer. The documentation I write once keeps working session after session, which is why this thing keeps getting more useful without me planning for it.

More tools, same scaffolding

The tools I lean on most share a shape: text in, text out, callable from a make target. That's what lets them attach to the loop without friction. The agent operates them like it edits a note. Each one adds a capability without changing how the system works.

  • Mermaid: diagrams written as .mmd files. The agent generates them, renders to PNG via mmdc, embeds the result in the note, and commits, all from a single make target. I use it for architecture sketches, process flows, the kind of thing I used to draw on a whiteboard and lose.

  • Marp: slide decks written in markdown with annotations, compiled to PDF and PowerPoint. I ask the agent to change a slide, it edits the .md, regenerates the PDF, and commits. The thing I value most is mundane: I can git diff between session 3 and session 7 of the same master's class.

  • Excalidraw: Obsidian stores its sketches as JSON inside regular .md files, so the agent edits them like any other text. Whiteboard-style diagrams that live next to the note that needs them, refined by prompt instead of by hand.

  • notebooklm-py: a client for the NotebookLM API. The agent passes a URL, a transcript, or a PDF and gets back topics, key points, and a structured summary. That's how external material lands in the vault with a consistent shape, without me writing every summary by hand.

  • yt-dlp: YouTube extraction. The vault uses it for talk-note metadata (title, channel, duration, captions), and also for downloading the video or the audio when I want a local copy of something I might lose access to.

  • markitdown: PDF and Word to markdown. It's how a paper or a slide deck someone shares ends up inside the vault as text the agent can read, summarise, and link to whatever else is already there.

The pattern repeats every time. If a tool speaks text and a Makefile target can wrap it, the agent inherits the capability. Adding a new one is a few lines of glue, not a rewrite.

What the agent doesn't do

The agent doesn't decide what's worth capturing. That judgment is still entirely mine. It doesn't surface connections I haven't thought of, at least not reliably enough to trust. It doesn't write the parts of notes that actually matter: the "applications in software" section of a mental model note, the personal reflection on why a talk changed how I think about something, the synthesis between two ideas I read six months apart.

What it does is remove the friction between having an idea and that idea being properly integrated into the vault. Before: I'd capture something in the inbox, know vaguely where it should go, not quite have the energy to do all the steps correctly, leave it in limbo. Now: the skill handles the scaffolding, I make the judgment calls, the note ends up in the right place with the right tags and no broken links.

The honest version is that the system requires active maintenance. If I'm lazy about updating the rules after learning something new, the next session starts with slightly worse context. The skills are only as good as the last time I refined them. The scripts catch what they're designed to catch. They are not magic.

But the direction is right. Each round makes the agent a bit more useful in this specific vault, and each round is cheap: a few lines of rules, a Makefile target, a refined skill. Unlike a one-off prompt, none of it evaporates when the session ends.

Where this leaves me

774 notes, 15 scripts, 33 Makefile targets, 6 skills, 3 rule files. Around 100 commits in the last two months, most of them from sessions where I was building something else and the vault maintenance happened as a side effect.

The test I use: after a week off, how long does it take me to pick up where I left off? With the previous system (no scripts, no rules, ad-hoc organization), reorienting took twenty or thirty minutes of reading through recent notes to figure out what was where. Now it's opening the vault, running make check-health, skimming recent commits. Five minutes.

Back to the question this post opened with: what makes Claude Code reliable in this specific vault? The short answer is that reliability doesn't come from the model. It comes from making conventions explicit. Rules the agent reads at the start of every session. Scripts that verify what the agent thinks it did. Skills that turn a vague instruction into a written protocol. The model fills in the parts that weren't worth automating. Everything else is documented, checked, and reused.

I've built this kind of thing in software teams: explicit conventions, automated checks, tools that hold on to what the team has figured out so new members don't start from zero. The dynamics are the same here. The agent is the new team member who read the onboarding docs, runs the checks before committing, and asks when something isn't covered. The documentation just happens to live in .claude/rules/.

Related reading

Sunday, April 12, 2026

My second brain: markdown, Dropbox, and an AI agent

1,222 notes, 24 categories, zero vendor lock-in. My knowledge management system fits on a thumb drive.

The starting point

The oldest notes in this vault are from June 2013. Talk notes, loose ideas, book quotes, technical decisions, reflections on teams and processes. They started out in Google Keep, in scattered files, in tools I no longer remember the name of. Over time I migrated them into markdown files by hand. Slowly, in bursts, never quite finishing.

The second brain always had valuable stuff in it. Interesting ideas, connections between concepts, reference material that had taken me hours to compile. I found notes when I needed them, connected ideas across sessions. But I had this persistent feeling that there was more in there than I was getting out. Hundreds of notes that didn't talk to each other. Knowledge that accumulated but didn't compound.

And then there was the Google Keep backlog. Over the years I'd piled up around 1,500 notes and links in Keep. Quick captures, things I meant to process "later." The problem was that Google Keep has no API, so getting stuff out was painful enough that I just... didn't. The backlog grew. Every time I opened Keep I felt the weight of it.

Last Christmas I decided to just rip the band-aid off. Exported everything via Google Takeout, deleted it all from Keep, and sat down with the raw files. Using AI I built a throwaway classification pipeline: a combination of heuristics and a human-in-the-loop process where the system proposed a category and I made the final call. In a couple of days, 1,500 notes were classified and integrated into the vault. Bye bye, Google Keep.

That was the moment it clicked. The friction of processing notes had been the bottleneck for years, not the lack of a system. Once I could generate tooling on demand to solve a specific problem, the backlog that had haunted me for ages just... dissolved.

Separately, I'd been curating recommended technical talks in eferro-picks for years. 855 talks, 465 speakers, gathered over 6 years. Another project with valuable information sitting in its own repo, its own structure, disconnected from the vault.

Both projects are now one. What I have is an Obsidian vault of markdown notes on Dropbox, versioned with Git, maintained by an AI agent that understands the structure. The talks from eferro-picks live inside the vault now. 402 of the 855 have full notes so far: all recent talks get them automatically, and I'm gradually backfilling the older ones that only had a title and a link. The vault is the source of truth for the talks, not the other way around. I even have automated pipelines to process new talks I watch and want to recommend (but that's a story for another post).

It's not an app. It's a folder of text files with a system on top. And for the first time in over ten years of note-taking, I feel like I'm getting out of it the value I always sensed was there.

Why plain text files

The most important decision in the system is the most boring one: everything is markdown. .md files I can open with any text editor, on any operating system, with no special tooling.

It sounds like a non-decision. It isn't. There's no database. No proprietary format. No server. If Obsidian disappears tomorrow, or Dropbox, or Claude, the notes are still readable. I can search with grep, edit with emacs, sync with rsync. The format will outlive whatever tool I'm using to read it this year.

Dropbox syncs across devices with zero configuration. Git versions everything, so every change is recorded, I can see diffs, I can roll back. Between the two I get sync and version control almost by accident. Dropbox keeps files up to date across machines, Git keeps the history.

There's a side effect I didn't appreciate until I was living it: I can edit a note on my laptop, close the lid, pick up my phone and keep writing where I left off. Or switch to another machine at home. No export, no sync button, no waiting. Dropbox just does it. Obsidian on mobile opens the same files, same links, same structure. It sounds trivial, but it removes the last excuse for not capturing an idea when it shows up.

Not sophisticated tools. Tools that work, and have been working for decades.

Obsidian is the reading interface. Wiki-links ([[Note]]) create a navigable knowledge graph, backlinks connect ideas both ways, the graph view shows you clusters you didn't know were there. But Obsidian is a view on files, not a platform. If something better comes along, I switch. The files don't care.

The vault's knowledge graph in Obsidian.
The clusters form naturally from wiki-links and shared tags.

And it turns out that "just text files" goes further than notes. Diagrams in the vault are Mermaid, a text format that renders into flowcharts and architecture visuals. Obsidian stores Excalidraw sketches as JSON inside regular .md files. The presentations for the master's program I teach live in Marp: markdown with a few annotations that compiles into slide decks, PDFs and PowerPoints. I can git diff a diagram the same way I diff a note, and an AI agent can generate a Mermaid flowchart as easily as it writes prose. To the agent it's all text.

The structure: PARA, loosely

Notes are organized following Tiago Forte's PARA methodology, without being religious about it.

Projects for things with a deadline or deliverable. Right now: a master's program I'm teaching, this blog, a house renovation. Areas for ongoing stuff: writing, professional network. Resources is where most of the vault lives, reference material organized by topic across about 24 categories. Archive for completed projects that should stop getting in the way.

If you've read my blog before, the topics won't surprise you. The most tagged subjects are engineering culture, AI, agile, continuous delivery, software design, architecture, product and XP. Throw in DevOps, lean, teams and testing and you have a pretty accurate map of what I spend my time thinking about. The vault just makes it explicit.

Then there's The Forest (the vault borrows the digital garden metaphor), a directory with Maps of Content: thematic indexes connecting scattered notes. And Sources, where the 402 talk notes live.

Beyond folders, notes carry two kinds of tags. Topic tags (on/software-design, on/lean, on/ai) say what a note is about. Maturity tags say how developed it is: state/seedling for a raw capture, state/budding for something I've worked on but isn't finished, state/evergreen for a note I consider solid. Most of the vault is still seedlings and budding notes. The evergreen ones are the minority, which is honest: note count and idea quality are different things.

The structure isn't perfect. What matters is that it's predictable. If I'm looking for a quote, I know it's in 3_Resources/Quotes/. Finished projects go to 4_Archive/. This predictability is what lets an AI agent work on the vault without asking me where things go.

The leap: an AI agent that gets the vault

Here's where it gets interesting. Claude Code is not a chatbot I ask things about my notes. It's an agent that operates directly on the files. Creates notes, edits them, runs scripts, checks the vault's health. All while following rules I've written over time.

The rules live in .claude/rules/, configuration files the agent reads at the start of every session. Where to put each type of note. What YAML frontmatter to include. Naming conventions. How to verify links aren't broken. Not suggestions. Constraints.

Here's what that looks like in practice. I say: "create notes for these 7 mental models." The agent creates 7 files in 3_Resources/system_thinking/, each with the right structure (core idea, software applications, limitations, connections), tags them on/mental-model, updates the central Map of Content in The Forest/Mental Models.md placing each in the right domain category, and before writing any wiki-link, checks that the target note actually exists. I don't touch a file. But the rules that made this work? I wrote those myself, one session at a time, encoding what I'd learned about how my vault should behave.

Three layers, one system

What makes this a system and not just "a chatbot writing files" is three layers working together. I keep coming back to this because it's the part people misunderstand.

The first layer is the agent with domain context. Claude Code doesn't see loose files. It knows a new talk note needs topics from the 80+ taxonomy and a link to the speaker's page. A quote goes in Quotes/ with the author's name as tag. A project has a deadline, an area doesn't. Rules give it semantics, not just file paths.

The second layer is 15 Python scripts behind 30 Makefile targets.

One group keeps the vault healthy: a script that parses every wiki-link and checks it against existing files, another that validates YAML frontmatter, another that finds stray images and moves them next to the notes that reference them.

A second group powers the talk pipeline: sync from eferro-picks, pull metadata from YouTube via yt-dlp, run content through NotebookLM, generate blog post HTML.

A third handles the master's presentations: Mermaid to PNG, Marp to PDF and slide decks.

The agent runs all of this through make targets. When it checks for broken links, it's not guessing. It's running a real script with real output.

The third layer is 6 skills. These aren't prompts. They're protocols: which tools to use, in what order, what to verify, what to ask me before proceeding. When I say "process this talk," the agent doesn't figure it out from scratch. It follows a written workflow that I've refined over multiple iterations. Same when I say "check vault health" or "organize the inbox." Each skill encodes a complete task, not a vague instruction.

Take away any one layer and the thing falls apart. Without scripts the agent would improvise something different every time. Without the agent the scripts are just CLI tools I'd have to remember to run. Without rules the skills wouldn't know what decisions to make.

How it actually evolved

The current state of the system is less interesting than how it got here. Because none of this was planned.

The talk pipeline started as a single script to sync a JSON with the vault. I was doing it by hand and it was tedious, so I automated the sync. Then I wanted the agent to be able to run it, so I wrote a skill. Then I wanted automatic topic extraction, so I plugged in NotebookLM. Then I wanted to publish talks as blog posts, so I wrote another script. Over a weekend, iterating with the agent. From copy-paste to a pipeline processing 402 talks and spitting out HTML.

The pattern repeats. I use the vault, hit a friction. Write a script for the mechanical part. Wrap it in a skill so the agent can orchestrate it with judgment. Add rules so the agent remembers the lesson next time. Now the agent is better at that task, which frees me to notice new frictions.

The master's program presentation rules followed the same arc. After session 3, I jotted down what worked and what hadn't. Slides had too much text. Extra material should be in separate files. Speaker notes needed a timeline. I turned those lessons into rules. From session 4 on, Claude Code applied them without me having to say anything. The rules became the shared memory between me and the agent.

Zero broken links

Of all the rules in the vault, one appears in three separate files. I consider it the most important: zero broken links.

In Obsidian, a wiki-link [[Something]] is a promise that "Something" exists as a note. If it doesn't, the link is noise. It suggests content that isn't there, pollutes the knowledge graph, blurs the line between what's real and what's aspirational. And broken links breed. One becomes five, five become thirty, and suddenly your graph is full of ghosts.

The rule is simple: if you're not sure a note exists, use plain text. The agent checks before writing any [[Concept]]. If the file doesn't exist, it writes "Concept" without brackets. After every edit, make find-broken-links. If it created broken links, it fixes them before moving on.

Prevention, not correction. Same principle as tests in code. Cheaper to not introduce the bug.

What this isn't

I don't want to oversell this.

It's not effortless. Rules need writing, scripts need maintaining, structural decisions need making. There are 15 Python scripts and 30 Makefile targets for a personal vault. Is that over-engineering? Probably, partly. Some of it is hobby. Some is me poking at what's possible when you point an AI agent at a folder of text files.

It's not a system where AI does the thinking. Claude Code doesn't decide what's worth keeping, how to categorize a concept, or which connections matter. I'm the one who decided mental models live in system_thinking/ regardless of their domain. I'm the one who decided that domain categorization happens in the MOC, not in the filesystem. The agent executes those choices at scale. But the design is mine.

And it's not for everyone. You need to be comfortable with a terminal, with Git, with text files. If you want a polished app with automatic sync and zero setup, use Notion. Seriously. It's fine.

The question I'm left with

Every time I codify a rule or a skill, the agent gets more capable. But also more opinionated. The rules reflect my decisions today: my taxonomy, my structure, my conventions. What happens when my thinking changes? Do the rules become inertia, or are they an explicit record of decisions I can consciously revisit?

Git has the full history. I can see when I added each rule and why. I can change them. But there's a gap between being able to change them and actually doing it when the system works well as-is.

After years trying tools, what works for me turns out to be the most boring stack imaginable: text files, a synced folder, an agent that knows the garden's rules. 1,222 notes and counting.

Whether the system helps me think better or just organize faster what I was already thinking, I genuinely don't know. Probably both. Probably the distinction doesn't hold up under scrutiny.

Related reading

The methodology and ideas behind this:

  • The PARA Method — Tiago Forte's original post on the organizational system this vault uses
  • Evergreen notes — Andy Matuschak's thinking on notes that evolve and compound over time, which inspired the seedling/budding/evergreen maturity model
  • Building a Second Brain — Tiago Forte's broader framework for personal knowledge management

The tools:

  • Obsidian — The editor I use as a view on the vault's markdown files
  • Claude Code — The AI agent that operates on the vault
  • Marp — Markdown to slide decks
  • Mermaid — Diagrams as text

Sunday, March 29, 2026

El libro que llevo 25 años intentando no tener que escribir

"Hoy, cuando la última moda es el AI-assisted coding, sonrío pensando que los principios que aprendí hace diez años siguen siendo los mismos." — del prólogo, por una ingeniera que trabajó en el equipo

Durante más de dos décadas he explicado las mismas ideas a los mismos tipos de equipos. Equipos distintos, empresas distintas, contextos distintos. Y sin embargo, el patrón se repetía con una regularidad que ya no puedo ignorar.

Equipos talentosos. Equipos capaces. Tecnología razonable. Y aun así: la sensación de correr cada vez más fuerte para avanzar cada vez menos.

Lewis Carroll lo describió mejor que yo en A través del espejo: "Aquí, como ves, se requiere correr todo cuanto se pueda para permanecer en el mismo sitio." Durante años pensé que esa metáfora era exagerada. Ya no.

Parte del problema es cómo pensamos sobre el software. Decimos que lo "construimos", como si fuera algo que se termina y queda ahí. Pero el software no se construye. Se cultiva. Es un sistema vivo que crece, cambia y se degrada. Y los sistemas vivos necesitan atención continua, no solo construcción.

He llegado a la conclusión de que lo más honesto que podía hacer era escribirlo.

De qué va el libro

"Menos software, más impacto" tiene un subtítulo que no deja mucho a la imaginación: Cómo evitar que tu equipo colapse bajo el peso de su propio código.

La tesis central es incómoda: el mayor problema de la mayoría de los equipos no es que escriban código malo. Es que escriben código de más.

El software existente consume recursos continuamente, lo uses o no. Cada funcionalidad añadida, cada integración, cada decisión de diseño que se acumula sin revisión tiene un coste que no aparece en ningún roadmap pero que aparece cada día. Lo llamo el coste basal del software, en analogía al metabolismo basal de un organismo: el gasto mínimo para seguir funcionando. Y como el metabolismo, si no se gestiona, crece hasta consumir toda la energía disponible.

El libro recorre cuatro grandes bloques:

  • Fundamentos: qué es el Lean Software Development y por qué el coste basal es el concepto central que lo conecta todo
  • Los cinco principios: eliminar desperdicios, amplificar el aprendizaje, decidir en el último momento responsable, entregar lo antes posible, empoderar al equipo
  • Calidad sostenible: por qué la calidad no es el enemigo de la velocidad sino su única base duradera
  • Pensamiento sistémico: optimizar el todo, integrar Lean con XP y mentalidad de producto, y qué pasa si no haces nada

Son 192 páginas. Basadas en más de 25 años de experiencia en equipos reales: Alea Soluciones, The Motion, Nextail, Clarity AI. Con casos concretos, conflictos reales y errores propios reconocidos. El libro incluye también las perspectivas de ocho profesionales que han vivido estas transformaciones desde dentro, en distintos roles y contextos.

Para quién es (y para quién no es)

Este no es un libro para quien quiere mejorar su código de forma individual. Hay libros excelentes para eso y este no es uno de ellos.

Es para quien toma decisiones sobre qué se construye, qué no se construye y qué se elimina. Engineering Managers, Tech Leads, Product Managers, CTOs. Cualquier persona con responsabilidad directa sobre la capacidad de un equipo a seis meses, un año, tres años vista.

Si tu día a día es decidir prioridades, gestionar capacidad y negociar alcance, lo que viene en el libro te va a resultar familiar. Y probablemente incómodo. Esa es la intención.

Por qué ahora

Hay mucha literatura sobre Lean, XP y Agile en inglés. En español, menos de la que debería haber. Y casi ninguna que combine los tres enfoques de forma integrada, con casos reales de equipos que conozco de primera mano.

Además, el contexto actual lo hace más urgente. La aceleración que trae la IA hace que las decisiones sobre qué construir y qué no construir sean más importantes, no menos. Amplificar la capacidad de un equipo que ya construye demasiado no resuelve el problema. Lo acelera.

El borrador está completo. Ahora viene la revisión, la edición y la preparación para publicación. Si te interesa estar entre los primeros en leerlo, escríbeme: eferro@eferro.net

Monday, September 01, 2025

My premises about engineering leadership and people management

As with software development, I find it useful to write down the principles that guide how I think about leadership and people management. These are not universal truths, but they are the foundations I rely on when building and leading engineering teams. By making them explicit, I aim to create clarity, alignment, and a shared understanding of how I see leadership, collaboration, and growth.

  1. People are not resources I don't believe in treating people as interchangeable units or "resources." People are creative, motivated, and responsible when given the right environment. My default stance is trust, not control. This aligns with Theory Y (Douglas McGregor): most people want to do good work if they are respected, trusted, and given meaningful challenges.
  2. Empower teams with ownership Teams work best when they own the whole problem end-to-end, from idea to operation. Ownership gives autonomy and accountability, while purpose provides alignment. An empowered team doesn't just execute tasks but makes decisions and cares about outcomes.
  3. Motivation is intrinsic The best results in knowledge work come from intrinsic motivation, not external rewards or pressure. As Daniel Pink highlights in Drive, autonomy, mastery, and purpose are the real drivers of excellence. My role as a leader is to foster these conditions, not to rely on carrots and sticks. 
  4. Learning never stops Engineering and product work are constant processes of discovery. We optimize for fast feedback, safe experiments, and collective learning. Mistakes are not failures to hide but opportunities to grow. A learning culture is the foundation of adaptability. 
  5. Enable experiments, eliminate waste, make quality inevitable My role as a leader is to create conditions for safe experimentation while relentlessly removing what doesn't add value. But more fundamentally, I must change the system so that working with quality becomes the most natural, simplest, and fastest path. This means building strong foundations, aligning incentives, and creating space for learning where teams ask "What's the worst that could happen?" with confidence. When quality is inevitable rather than heroic, we create virtuous cycles where technical excellence enables bold experiments and meaningful impact.

These are my personal premises about engineering leadership and people management. They are not universal truths, but the foundations I rely on when building and leading teams. I believe that making these principles explicit helps create clarity, alignment, and better collaboration.


References:

Saturday, August 09, 2025

Rediscovering my joy of coding:

How AI Is Shaping My Journey as a Tech Leader

I’ve been near a keyboard since the mid-80s, but I only started programming professionally around 1997. Fast forward nearly 30 years, and much of my career has been spent leading teams and working closely with product—so I’ve been coding less directly.

But AI has changed that. Now I can jump back in as a team contributor (I prefer this term because software development is really a collaborative effort) while staying in my leadership role. I can explore new technologies, make quick tweaks, and run experiments without becoming a bottleneck for the team. The usual hurdles—like boilerplate code or ramping up on a new stack—have shrunk.

This has supercharged my learning and experimentation. I can run more tests, dive into new tech, and rediscover the joy of focusing on what truly adds value—without the tedious overhead that used to slow things down.

We’re at a unique moment: with AI as our companion, we can build more software, handle complexity, and reinvent how we work together.

To fellow tech leads: are you feeling this shift too? I’d love to hear if this transformation excites you as much as it does me. We’re in the midst of a profound change, and it’s up to us to shape this new chapter.

Thursday, April 10, 2025

Vibe Coding III: Complexity Creeps—Unless You Don’t Let It

Getting Back to My Picks

Over the past few days, I revisited the development of eferro Picks. The project had been well received, and I’d gotten some interesting feedback, so I decided to give it a proper push. But this time, it wasn’t just another playful exploration. The project had grown in complexity and was starting to demand a more deliberate approach—especially if I wanted it to scale or stay maintainable.

My first step: simplify the code, strip out anything superficial, and wrap everything in tests to make the project more sustainable.

The next step was to process all the feedback I had received about the site and implement some improvements that would make the experience smoother and more intuitive. This included better navigation, clearer tooltips, and a toggle to filter talks that actually had notes. It was a great excuse to turn real user feedback into practical functionality—while continuing the vibe coding experiment in a slightly more purposeful direction.

https://eferro.github.io/eferro-picks-site/

The AI as My Pair Programming Partner (With Superpowers and Flaws)

For this session, I continued my vibe coding experiment, but with a twist. Since my experience with front-end technologies like TypeScript, React, and Tailwind CSS is limited, I focused solely on accepting or rejecting the AI's proposed changes. I didn’t review or modify the code directly—instead, I observed the AI’s behavior and guided its direction from a higher level. It was pure vibe coding: trusting the AI and seeing where it would lead.

I used the Cursor Pro IDE, following the vibe coding rules I outlined in the first post of this series (Vibe coding: building things from curiosity and flow). That meant focusing on flow, intuition, and rapid iteration—even when partnering with an AI. Those original principles shaped how I interacted with it, emphasizing exploration over rigid planning.

In this new phase, the AI stopped being just a tool and started acting more like a pair programming partner. One that—despite chaotic moments—can be surprisingly effective when guided with care and intention. I say “guide” because without boundaries, it tends to suggest overly generic or needlessly complex solutions. Almost like it's channeling the collective ego of every public repo out there.

Left unchecked, the AI naturally gravitates toward generality, abstraction, and unnecessary flexibility—just like many of us do when we’re overthinking or trying to be clever.

This approach helped me refactor with focus, prioritizing simplicity and clarity. But it wasn’t all smooth sailing—and I think it’s important to be transparent about that.

During the process:
  • Two or three times, I had to stop because the AI entered loops it couldn’t escape.
  • Once, it even pushed invalid changes directly to production (I work in trunk).
  • Two or three times, I had to revert committed changes just to get back to a stable state.
  • At least twice, when a test wouldn’t stabilize, the best option was to delete it, move on, and return later with fresh eyes. That worked far better than endless poking.


These moments—while frustrating—reinforced something I already believed: the only way to build sustainably with this much raw power at my fingertips is to work in small, safe steps.


The Power of Small Safe Steps (Now More Than Ever)

One of the clearest takeaways from this session: with this much speed and assistance, working in Small Safe Steps becomes more essential than ever.

It’s valuable to know what I want to achieve, have techniques to move forward in parallel, and break tasks into manageable chunks. In practice, most of these “steps” were completed in sessions of 25 minutes or less. Each one designed to be:
  • Small: a change that takes just a few minutes.
  • Safe: unlikely to break production code or existing tests.
Also, due to my current responsibilities, I can only code in short, scattered bursts. I no longer have the luxury of regular pair or ensemble sessions. That’s why the benefits of small steps are fundamental for me—especially:
  • Interruptibility: I can pause anytime without losing the thread.
  • Safety: Each change is low-risk and easy to roll back.
  • Autonomy: I can keep moving forward, even solo, without creating chaos.


This way of working also offers continuous feedback. Geepaw Hill’s article MMMSS: The Intrinsic Benefit of Steps describes this beautifully. I highly recommend reading the full Many More Much Smaller Steps series—it sticks with you.

Small Improvements, Real Impact

In these sessions, I also tackled some of the feedback I had received.

For example, the note icon next to some talks was unclear. After digging into the data with the AI, we discovered that many of those records didn’t contain actual notes—just whitespace or line breaks. So:
  • I implemented a filter to clean those up.
  • Added a tooltip explaining what the icon meant.
  • And (because experimenting is cheap) added a toggle to filter talks with real notes.
Another piece of feedback was trickier: when users navigated to a talk and returned, they lost their filters and scroll position.

This was tough—mainly due to my lack of frontend experience. The AI kept trying random libraries and approaches, switching strategies mid-flight. It felt like pure trial-and-error with no clear rationale.
Things only improved when I stepped in with a specific suggestion:
“Can you change the approach and just use a specific key for the index (scroll_index) so we can use this key when coming back? This way we avoid the problem of overwriting the key.”
The AI immediately responded:
“Ah, that’s a much simpler approach! Instead of handling different paths and normalizing them, we can:
  • Use a specific key for the index page scroll position
  • Save it when leaving
  • Restore it when returning
  • No need to handle paths or base URLs. Let me update the code.”
This moment captured a recurring pattern: complexity is still my responsibility
Left unchecked, the AI naturally gravitates toward generality, abstraction, and unnecessary flexibility—just like many of us do when we’re overthinking or trying to be clever.

But if I pause, question, and steer things back toward simplicity, the AI follows—with surprising grace.

I can (and must) be the guardian of simplicity—with or without AI.

A Retrospective with the AI (and Tangible Results)

In the middle of all this, I ran a mini-retrospective. I asked the AI:
“We’ve been working together for a while. I think you already know what concerns me. Can you describe our workflow and what behaviors you've changed based on my instructions?”
The AI replied:
“Our workflow has evolved into a highly collaborative process where:
  • We work in small, focused steps
  • Each change is preceded by clear reasoning
  • You maintain control
  • I provide options and wait for your decisions
  • We verify each change before moving forward
  •  Communication is direct and natural
I’ve adapted to:
  • Present one change at a time
  • Show my thought process
  • Ask for confirmation before proceeding
  • Focus on practical, simple solutions
  • Maintain test coverage
  • Keep methods small and focused
  • Would you like me to adjust anything? 😊”
Then I followed up:

“Several times I’ve had to revert your changes because you didn’t run the tests before committing. Sometimes even several commits at once.
  • Why do you think this happened?
  • How could we have avoided it?
  • What have we learned?
  • How should we adapt to keep complexity under control?
The AI responded:
“To improve our process, I suggest:
New workflow steps:
  • Make one small change
  • Run tests immediately
  • Fix issues
  • Get your review
  • Only then commit
  • Never push without your explicit approval
Quality gates:
  • All tests must pass
  • Changes must be minimal
  • Each commit should be independently testable
  • No pushing without verification
Communication improvements:
  • Always report test status
  • Ask before pushing
  • Be explicit about what’s tested
  • Show test results

Would you like me to implement these changes in our workflow? 😊”
And the best part? It followed through. For the rest of the session, it ran tests before suggesting anything and asked for confirmation before every commit or push.

Closing: Being a Responsible Coder, Even When Alone

Will the AI forget all this once I close the IDE? Probably. But I’ve learned that these kinds of iterations and retrospectives have value. Therapeutic for me. Educational for the AI—at least within the session.

This experience reinforces the critical importance of working in Small Safe Steps, especially when collaborating with powerful AI. It’s not just about speed, but about maintaining control and understanding.

Continuous simplification is key. Left unchecked, complexity always grows. I have to actively fight that—and help the AI do the same.

Ultimately, it’s up to me to be the guardian of simplicity.

And given my current role, I don’t get to code as much as I’d like—certainly not in pair or ensemble settings. So this is the closest I get to coding responsibly. Because anyone who knows me knows:
 Leaving me to code alone is rarely a good idea. :)


Previous posts in the series:

Related links:

Monday, April 07, 2025

The Phrases That Power My Leadership

Over the years, I’ve noticed that certain phrases have become central to how I lead teams. They're not just casual remarks—they're powerful tools that shape our culture and drive our decisions.

My leadership style leans more on intuition than rigid structure. But through reflection, I’ve realized I often return to the same phrases. These serve as mental shortcuts that influence how we work, decide, and collaborate.

"What’s the worst that could happen?" encourages experimentation without fear. It reflects a mindset of calculated risk-taking and a commitment to creating a safe space for innovation. This question only works if we can confidently answer, “Nothing serious—and we can fix it quickly.” That confidence comes from a strong foundation: technical excellence, sound design, automated testing, and continuous deployment. 


When we trust our systems and processes, experimentation becomes second nature. Then, questions like “What’s the next seemingly impossible goal we’ll accomplish?” don’t sound wild—they become grounded ambition. This mindset grows by breaking down complex problems and making thoughtful decisions step by step.

"Can we avoid doing it?" and "Can we achieve the same impact with fewer resources?" drive us toward efficiency. These align with Lean principles: reduce waste, maximize value. They help us cut complexity and focus on what truly matters. "What if we only had half the time?" forces us to prioritize and think about vertical slicing, ensuring we get feedback sooner. When technical quality is high, it’s easier to identify what’s unnecessary, simplify with confidence, and adapt quickly. Even a suggestion like “Let’s remove it and monitor the impact; we can restore it if needed” becomes a safe, low-risk move. In an environment with solid observability, metrics, and rollback capabilities, deletion becomes just another experiment. Another phrase I often use is, “Don't do anything I wouldn't do.” This encourages a sense of shared responsibility and ensures that everyone feels empowered to make decisions within the established boundaries and values of the team. It promotes trust and reinforces that we're all in this together.

These phrases go beyond individual decisions. They spark a positive feedback loop:

  1. Technical excellence builds speed and confidence.
  2. That enables experimentation, learning, and impact.
  3. That impact strengthens the team’s autonomy and trust within the organization.
  4. That trust leads to more investment—and more progress.

It’s a virtuous cycle. It doesn’t happen overnight, but once it begins, it changes everything.

In the end, these phrases work because they reflect a way of working built on ambition, focus, and care. We aim for innovation and execution while supporting each other along the way. And they work because there are teams who don’t just understand them—they live them every day.

This approach is also only possible thanks to the patience and insight of my colleagues. Thank you for joining me in exploring new ideas—and for steering us wisely when needed.

These are just a few of the phrases that guide my leadership. I’d love to hear the ones that guide yours. Feel free to share them in the comments below!

Related Articles (for more context and related principles):


Ultimately, these phrases—and the principles behind them—help build a culture of trust, innovation, and continuous improvement. It’s about empowering teams to do their best work and make a real impact.


Sunday, April 06, 2025

I've launched eferro-picks-site: my personal selection of talks on software development

Over the years, I've listened to hundreds of talks on software development, product, Lean, Extreme Programming, and related topics. I usually listen to them while walking, and when a talk really resonates with me, I add it to my personal database. Right now, I have over a thousand talks tracked, and I've marked around 200 of them with a 5-star rating — these are the ones featured on eferro-picks-site.


The curation and logging process behind these talks has been ongoing for more than 7 years. What’s new is that I’ve finally put the best of them into a website that’s easy to browse and continuously updated. It’s a simple project with one goal: to share the talks that have helped me grow — in case they can help someone else too.

The talks are grouped by topic, and only those I've rated 5 stars make it to the site. The selection is personal and opinionated. It’s not meant to be exhaustive or neutral — it’s my perspective, based on what has resonated with me most.

eferro-picks-site


A small project, powered by AI and Vibe Coding

While the curated database has been growing for years, turning it into a browsable site was a small, recent project — and a learning opportunity. I kicked it off using a Vibe Coding approach: following flow, curiosity, and feel, rather than strict planning.

I had no real frontend experience, so I relied heavily on AI to explore, experiment, and build. It’s helping me learn how to work effectively with AI as a development partner, and at the same time get slightly more familiar with frontend technologies (which are mostly new to me). The site is built with React, hosted on GitHub Pages, and fed from an automatically updated JSON file based on my Airtable database.

You can check out the code on GitHub, and I'm happy to receive feedback or corrections. That said, the curation itself will remain personal 😊.


If you find something useful — or if any talk really resonates with you — I’d love to hear about it. You can reach out on social media or open an issue on the repo.

And if you’d like to support my work and help me keep sharing things like this, you can do so with a coffee: https://ko-fi.com/eferro ☕️

Hope it helps!




Saturday, April 05, 2025

📚 Learning on the Go 🎧

One of the things that has helped me the most in recent years to keep learning—despite not always having time to sit down and read—is the audiobook format.

It’s not the best fit for every topic (especially deeply technical ones), but for many others, it’s just perfect. I usually go on long daily walks (1.5 to 2 hours), and I use that time to listen to books on leadership, systems thinking, organizational culture, product development, agility, technology, and strategy.

Thanks to that, I’ve been able to explore subjects I wouldn’t have the time or energy to dive into otherwise. Audiobooks don’t replace paper books for me, but they definitely complement them. They keep me connected to ideas that inspire me or help me reflect on my work.


Some of these books I’ve listened to more than once. Others made me buy the print version to dive deeper or take notes. Each one has added something valuable to my journey.

Do you also use walks or commutes as learning time? I’d love to hear what works for you.

Friday, April 04, 2025

Vibe coding II: when flow meets tests

A few weeks ago, I wrote about vibe coding as a light, curiosity-driven and deeply personal way to build small projects without pressure. If you haven’t read it yet, here’s the link: Vibe coding: building things from curiosity and flow.

Back then, I shared how SimpleCalendar app and eferro Picks site came to life without a fixed plan — just following my instincts, what felt good in the moment, and playing with tools like Lovable and Cursor. But once SimpleCalendar started to feel “good enough,” a natural question popped up:

What if I want to improve it later? How do I avoid breaking things that already work?

A new phase of the experiment

That’s when a second phase of the experiment started: introducing a strong testing strategy, not as part of the design, but as a safety net for the future.

I didn’t use TDD. Quite the opposite — tests came after the fact. And that changes things. They didn’t help shape the architecture or drive design decisions. The structure I ended up with was just what had emerged from the flow — with its quirks and lucky guesses. But what tests did give me was confidence. Confidence to touch code without fear. Confidence to think about new features without worrying about regressions.

What test comes next?

One of the most interesting parts of this phase was using AI again — but in a different role.

I wasn’t asking it to code as much as to help me decide what test would give me the most confidence next.

Sometimes it worked really well. It pointed to areas I hadn’t thought of testing yet.
Other times… well. Let’s just say I found myself in a trial-and-error loop, poking at things, trying to get the test to pass. Without much frontend experience, it really felt like being a kid blindly hitting a piñata with a stick. Try, miss, try again… until something clicked.


And in a couple of cases, I got stuck in endless loops. The best thing I could do was revert to the last stable point. Small steps and good version control — still essential, even (especially) when working with AI.

An emerging strategy

Looking back, the test suite ended up with a pretty solid and layered structure:

  • I started with basic unit tests — validating components and utilities.
  • Then came integration and hook tests, managing state and interactions.
  • Later, I added coverage tools, edge cases, quarter navigation, grid behavior…
  • And finally, I polished it: test structure, readability, timezone handling, transitions…

It turned into a kind of after-the-fact test pyramid. And even if it didn’t help design better code, it gave me a real sense of safety moving forward.


Current tests execution

Assisted refactoring: the other half of the experiment

During the initial build phase, I made it a point to regularly pause and ask the AI to look for refactors, simplifications, or unused code.
That played a big role in keeping complexity under control. When the time came to introduce tests, the codebase was in a reasonably clean and manageable state — not by accident, but by design.

Turns out, you can keep things tidy even in flow mode, if you ask the right questions. And if you guide it well, the AI can be surprisingly helpful with that too.

Complexity is still our problem

And here’s something I really want to highlight — especially now that we can build so fast, test ideas on the fly, and move with the kind of speed that used to feel like sci-fi: complexity is still our responsibility.

Just because something works doesn’t mean it’s well built.
Just because we built it fast doesn’t mean it will survive the next change.
The temptation to say “let the AI deal with the mess” is real — but dangerous.
Complexity kills, with or without AI.

And because it’s now so easy to build things, it’s more important than ever to keep complexity in check.

When vibe works — and when it doesn’t

This AI-assisted approach worked really well for these small apps with no hard requirements — where discovering what I wanted was part of the process.

But for components or applications that need to live inside a broader, evolving ecosystem, this way of working wouldn’t be appropriate — at least not today.

We’re still learning how AI can support sustainable, scalable product development within a real team, with real constraints, and real users.

That’s a different kind of challenge. And we’re just getting started.

"We are uncovering better ways of developing software by doing it and helping others do it."

References & Useful Links