<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Nicolás Baglivo</title>
    <link>https://engineering.nbaglivo.dev/</link>
    <description>Engineering ideas and projects by Nicolás Baglivo.</description>
    <language>en</language>
    <lastBuildDate>Tue, 11 Aug 2026 00:00:00 GMT</lastBuildDate>
    <atom:link href="https://engineering.nbaglivo.dev/feed.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>The AI engineer manifesto</title>
      <link>https://engineering.nbaglivo.dev/writing/the-ai-engineer-manifesto.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/the-ai-engineer-manifesto.html</guid>
      <pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<ul>
<li>You'll decide what's yours to own before the AI is in the room.</li>
<li>You'll make every decision that tracks to something that matters.</li>
<li>You'll have an opinion about the things that matter. You won't let the AI form an opinion for you.</li>
<li>You won't allow situations where the AI can <a href="https://thedecisionlab.com/reference-guide/psychology/choice-architecture" target="_blank" rel="noopener noreferrer">choice-architect</a> you into something.</li>
<li>You won't mistake confidence for truth. You'll always ask for evidence.</li>
<li>You will feel the friction. You won't gloss it over, and you won't let plausibility pass for truth.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Complexity doesn't spike. It drifts.</title>
      <link>https://engineering.nbaglivo.dev/writing/complexity-doesnt-spike-it-drifts.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/complexity-doesnt-spike-it-drifts.html</guid>
      <pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Keeping complexity low was always a goal worth fighting for. Every team I've been part of that took it seriously ended up in a better place. Every team that didn't eventually paid for it.</p>
<p>In the age of agentic development, this matters more than it ever did. The rate at which we can generate code has gone up dramatically. The rate at which complexity can accumulate has gone up with it.</p>
<h2>The signal most people miss</h2>
<p>If your developers look at a task and genuinely don't know what it's going to take — not roughly, not approximately, but at all — that's a strong signal of a complex system.</p>
<p>Not &quot;this is tricky.&quot; Not &quot;I'll need to think about it.&quot; The more concerning version: there are too many unknown unknowns to even sketch the shape of the work.</p>
<p>The temptation in that situation is to say &quot;I'll figure it out as I go.&quot; That's reasonable for learning. It's not reasonable for complexity management, because figuring it out as you go is exactly how you end up adding more of it. You make choices under uncertainty, at speed, without the context to see the tradeoffs. And the system gets a little worse with each one.</p>
<h2>What this means before you hand anything to an agent</h2>
<p>A developer handing work to an AI without understanding what the change entails is not doing themselves a favor. They're setting themselves up to review code they can't properly evaluate.</p>
<p>Before delegating a task — to an agent or anyone else — the person responsible for that change should be able to:</p>
<ul>
<li>Name the parts of the system the change touches</li>
<li>Articulate the main tradeoffs in the approach</li>
<li>Identify the places where complexity could creep in</li>
</ul>
<p>That doesn't mean having the full solution figured out. It means having enough orientation to make conscious choices when reviewing a plan, rather than just accepting the first thing that compiles and seems to work.</p>
<p>This step isn't optional. It's what makes the rest of the workflow useful.</p>
<h2>Agents amplify what's already there</h2>
<p>An agent working on a complex system doesn't simplify it. By default, it makes it more complex — because it reads the patterns in the existing code and extends them. It doesn't question whether the pattern should exist. It just follows it.</p>
<p>If the system has accumulated bad abstractions, inconsistent naming, unclear boundaries, unclear responsibilities — the agent will replicate all of that and take it further. Faster than a human would. With more surface area.</p>
<p>This is the part that doesn't get talked about enough. The optimism around AI-assisted development assumes we're building on a solid foundation. A lot of systems aren't. And &quot;move faster&quot; applied to a shaky foundation is a liability, not a feature.</p>
<h2>Why it feels fine until it doesn't</h2>
<p>Complexity is rarely caused by one catastrophic mistake. It's the sum of many small ones — each defensible on its own, none catastrophic in isolation.</p>
<p>A slightly unclear abstraction. A shortcut that seemed temporary. A boundary that wasn't quite right but close enough. A tradeoff that made sense at the time and nobody ever revisited. Each one is forgettable. Together, they're the reason a simple feature takes three weeks and nobody knows why.</p>
<p>The dangerous thing is how reasonable it looks, one decision at a time. &quot;This is a small thing&quot; is almost always true. &quot;This will compound&quot; is almost always also true — and much less visible.</p>
<p>Now imagine this with no human in the loop. Agents running end-to-end, generating code at scale, each output building on the previous one. Every small complexity choice amplified across dozens of cycles before anyone reviews the result. That's not a hypothetical. That's where things are heading.</p>
<h2>Zero tolerance has to be systematic</h2>
<p>You can't rely on individual developers to catch this consistently. Not because they're careless, but because it's genuinely hard to notice in the moment, and there's always pressure to ship. Expecting people to consistently hold the line through goodwill alone isn't a strategy — it's wishful thinking.</p>
<p>What actually works is encoding the standard into the process. Guidelines for what &quot;done&quot; means that include complexity considerations. Skills and tools that make it easy to check whether a change is making things worse. Review steps that ask the right questions by default, not just when someone remembers to. The anchor needs to exist before the work starts, not get applied after the fact.</p>
<p>The goal isn't to create a bottleneck. The goal is to make zero tolerance automatic — so that the speed you're gaining with AI isn't being spent on debt you'll have to pay back at a much higher rate later.</p>
<p>Humans in the loop won't scale to match the volume of code we're now capable of generating. That's the right problem to solve for — not &quot;how do we review more&quot; but &quot;how do we build systems that stay reviewable.&quot;</p>
<h2>There's no single fix</h2>
<p>There's no one tool or practice that solves this. Sustainable agentic development is a stack of guardrails, not a single switch.</p>
<p>You'll need review processes — not for everything, but for the things that matter. You'll need humans in the loop at the right moments, not because you don't trust the agents, but because someone needs to know what's actually going on. You'll need observability so that when something drifts, you can see it. You'll need synthetic testing and regular testing, because at the speed code is being generated you can't catch regressions manually. All of it.</p>
<p>But these guardrails operate at different stages, and not all stages are equal. Some catch problems after they've already been built. Others prevent them from being built in the first place.</p>
<p>Anchored Agentic Development is one framework I've been developing that operates early — before a line of code is written. The idea is to capture architectural decisions as ADRs and make them available as context to every agent and developer before work starts. Before execution, a plan exists and gets checked against the architectural record. Agents build from direction you set, not from whatever they can infer from the existing codebase.</p>
<p>It doesn't eliminate the need for the other guardrails. But because it operates at the start of the loop — at the planning stage, before the build — it prevents drift that everything else would only catch after the fact. That's what makes it worth putting in place early: not that it's sufficient, but that it's upstream of so many other problems.</p>
<p>When the complexity eventually wins — and it will, in systems where nobody took this seriously — people will blame the AI. They'll say the tools failed to deliver on their promise. That the technology wasn't ready.</p>
<p>I don't think that's where the failure will be.</p>
<p>The AI will have done exactly what it was asked to do. It will have generated code, followed patterns, extended the system in the direction it was already going. The failure will be in how we used it — what we asked it to build on, what we skipped, what we assumed it would handle.</p>
<p>That's our responsibility. Not Anthropic's. Not OpenAI's. Ours.</p>
<p>It's also completely within our control to get right.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Anchored Agentic Development, Part 2</title>
      <link>https://engineering.nbaglivo.dev/writing/anchored-agentic-development-part-2.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/anchored-agentic-development-part-2.html</guid>
      <pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate>
      <description>The payoff</description>
      <content:encoded><![CDATA[<p><a href="https://engineering.nbaglivo.dev/writing/anchored-agentic-development.html">Part 1</a> covers the mechanism: set the anchor with ADRs, keep the context available, check plans against it before anyone builds. This part is about what that gets you when you actually run it — the loop it forms, and why it compounds instead of just holding steady.</p>
<h2>The loop over time</h2>
<ol>
<li><strong>Decide</strong> — write and decide the ADR</li>
<li><strong>Context available</strong> — to any work, any agent, any trigger</li>
<li><strong>Plan</strong> — approach reviewed against decisions before execution, by a human or an agent</li>
<li><strong>Build</strong> — against direction, not inference</li>
</ol>
<p>Each ADR makes the next session smarter. Each build that stays on track is one less drift to clean up. The system compounds — and that compounding is neg-entropy in action. You're not just preventing disorder; you're actively accumulating structure. The architecture becomes more coherent over time, not despite continuous work happening, but through it.</p>
<p>The decisions are recorded and available. Every new decision is checked against prior ones at write time. Every implementation is checked against the record before build time. The work reinforces the foundation instead of eroding it.</p>
<p><strong>Context engineering matters more as the system grows.</strong> A handful of ADRs fit comfortably in a context window and the process works cleanly. As the system grows and decisions accumulate, loading everything starts to hurt — more tokens, less signal, worse results. Left unmanaged, the context itself becomes entropic: too much noise, too little signal, and the coherence you built up in the ADR history stops translating into coherent output. The same force you're trying to counter in the codebase shows up in the context.</p>
<p>That's a context engineering problem, not a process problem. The framework still holds. The tooling around it needs to evolve. Domain tags help — load only the ADRs relevant to what you're building right now. But at a certain scale even that isn't enough: you may need semantic search over your ADR history, retrieval-based approaches that surface the most relevant decisions given the task, or purpose-built agents that do the selection for you. The right solution depends on the size and shape of your system.</p>
<p>Tools like ctx are a good starting point. They work well at smaller scale. What replaces or extends them at larger scale is an open question — one worth solving when you hit the ceiling, not before.</p>
<p><strong>You can automate as much of this as you want.</strong> Conflict checking between a new ADR and prior ones is a well-defined task — you can build an agent for it, a CI check, whatever fits your setup. The plan review step can have guardrails. Parts of the ADR-writing process can be scripted.</p>
<p>Automate what makes sense. The thing that doesn't get automated is direction. You know what the direction is because you authored it. That's the point of the framework — not to keep humans in every loop, but to keep humans in the right loop. The one that happens before everything else.</p>
<p>The habit is the point. Direction before delegation, every time. The cost is low — one ADR per decision. The payoff is that AI always has something real to work from.</p>
<h2>Tooling</h2>
<p>I'm actively building tools to make this process faster and more effective. These are what I have so far. As the process gets more adoption, better and different tools will emerge — from me and from others. If you build something that fits here, or have ideas worth discussing, reach out.</p>
<p><strong>ctx</strong> — assembles tagged markdown files into a single context file. Pull all ADRs for a service or filter by domain. A good starting point for a smaller ADR history.</p>
<p>→ <a href="https://ctx.nbaglivo.dev" target="_blank" rel="noopener noreferrer">ctx.nbaglivo.dev</a></p>
<p><strong>claude-mem</strong> — a good alternative to ctx when you want more automation in your local workflow, particularly when writing or reviewing ADRs. Less manual setup, more out of the way.</p>
<p>→ <a href="https://github.com/thedotmack/claude-mem" target="_blank" rel="noopener noreferrer">github.com/thedotmack/claude-mem</a></p>
<p><strong>The adr skill</strong> — a Claude Code skill that handles ADR creation: enforces structure, checks for conflicts against existing ADRs, generates the file. Use it from Claude Code with <code>/adr</code>.</p>
<p>→ <a href="https://github.com/nbaglivo/anchored-agentic-development/tree/main/skills/adr" target="_blank" rel="noopener noreferrer">github.com/nbaglivo/anchored-agentic-development/tree/main/skills/adr</a></p>
<p><strong>The review-adr skill</strong> — validates a draft ADR against your existing history. Checks for missing rationale, conflicts, superseded decisions, and gaps before you push for peer review. Use it from Claude Code with <code>/review-adr</code>.</p>
<p>→ <a href="https://github.com/nbaglivo/anchored-agentic-development/tree/main/skills/review-adr" target="_blank" rel="noopener noreferrer">github.com/nbaglivo/anchored-agentic-development/tree/main/skills/review-adr</a></p>
<p><strong>Unfold</strong> — automatically monitors ADR changes in GitHub and uses LLMs to derive a living architecture model from them. When an ADR is merged, Unfold updates the model and surfaces it as context for agents, engineers, and PMs alike. Agents plan with full architectural awareness — drift gets caught before a line is written. Engineers learn the system by querying it. PMs can ask &quot;how many teams does this feature touch?&quot; and get grounded answers for risk analysis and planning. Architecture stops being a document nobody reads and becomes context everyone can use.</p>
<p>→ Coming soon.</p>
<h2>Starting with no ADRs</h2>
<p>Most systems have history that was never written down. You're not starting from zero — the knowledge exists in the code, in a half-maintained wiki, in your own memory. It just needs surfacing.</p>
<p>The bootstrapping process is covered in full <a href="https://engineering.nbaglivo.dev/writing/bootstrapping-adrs-when-you-have-none.html">here</a>. The short version: use AI to extract decisions from the codebase, from documentation, and from your own head. Treat the first ADRs as drafts. Relax the immutability rule until they stabilize. Once the history is accurate, apply the full process going forward.</p>
<h2>A note on tooling and AI providers</h2>
<p>This framework is described using Claude and Claude Code because that's what I use. The process works with any capable AI — the tools that load context may need to be adapted, but the loop is the same. Write the decision. Load it as context. Plan before you build.</p>
<p>Reach out at <a href="mailto:hi@nbaglivo.dev">hi@nbaglivo.dev</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Anchored Agentic Development</title>
      <link>https://engineering.nbaglivo.dev/writing/anchored-agentic-development.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/anchored-agentic-development.html</guid>
      <pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate>
      <description>Against entropy</description>
      <content:encoded><![CDATA[<p>Agents and developers are building from your codebase continuously — triggered by a Linear ticket, a Slack message, an incident, a developer opening their editor. Leave them to do their thing without direction and you get entropy: every agent making its own decisions, patterns diverging, the system fragmenting a little more with every build. It's not anyone's fault. It's just what happens when there's no shared context to build from.</p>
<p>Apply this process and you get the opposite — neg-entropy. The system becomes more coherent over time, not less. Every decision captured adds to the foundation that keeps the next build aligned.</p>
<p>AAD is a framework for making sure the right context exists and is available. The human's job is to architect: make decisions, capture them as ADRs, build up a record of direction over time — with AI as a thinking partner. The result is a body of context that any agent, any developer, any automated workflow can draw from at any moment. The architecture stays coherent not because someone is reviewing everything, but because the direction was there before the work started.</p>
<p>Set the anchor. Then let the work happen.</p>
<p>The idea behind this framework started taking shape in a post about using ADRs as context for Claude — <a href="https://engineering.nbaglivo.dev/writing/giving-claude-architectural-memory.html">Giving Claude architectural memory</a>. That post is where the core insight first got written down. This framework is what grew from it.</p>
<h2>The anchor</h2>
<p>The anchor is what prevents entropy. Without it, agents build freely — each making their own decisions, each drifting slightly further from the intended architecture. The drift is quiet at first. Then it compounds.</p>
<p>The anchor is the ADR history: a record of architectural decisions that anything building from the system can orient around. Setting it is the human's job — not because AI can't write decisions, but because the anchor only holds if someone owns it. That ownership is what makes it a real constraint rather than a suggestion.</p>
<h3>The workflow</h3>
<ol>
<li>Make the decision — with AI as a thinking partner.</li>
<li>Validate the draft against prior ADRs — catch conflicts, gaps, and superseded decisions before anyone else sees it.</li>
<li>Push a PR — get it peer reviewed by your team.</li>
<li>Merge — the decision is made. It is now available to your developers and agents.</li>
<li>Optionally, if there's implementation work to do, start your agentic development — local or cloud.</li>
</ol>
<h3>Making the decision</h3>
<p>An ADR records a single architectural decision: the context that made it necessary, what was decided, and what changes as a result.</p>
<p><strong>Context</strong> — why this decision needed to be made. What was missing or underdetermined. If this supersedes or extends a prior ADR, say so here explicitly.</p>
<p><strong>Decision</strong> — what was decided, with the rationale close to the decision itself. Don't separate what from why.</p>
<p><strong>Consequences</strong> — what changes now. What needs to be built. What constraints are introduced.</p>
<p>What an ADR is not:</p>
<ul>
<li>Not a ticket. ADRs record decisions, not work items.</li>
<li>Not documentation of the current state of the system. If the code diverges from a decided ADR, the ADR is correct — the implementation is the problem.</li>
<li>Not a living document once decided. If the decision changes, a new ADR supersedes it. The history stays intact.</li>
</ul>
<h4>The template</h4>
<p>→ <a href="https://github.com/nbaglivo/anchored-agentic-development/tree/main/templates" target="_blank" rel="noopener noreferrer">github.com/nbaglivo/anchored-agentic-development/tree/main/templates</a></p>
<h4>Where to store them</h4>
<p><code>docs/adrs/</code> in your repository. Named sequentially: <code>ADR-NNNN-short-description.md</code>.</p>
<p>Sequential naming gives you a rough timeline and makes cross-referencing unambiguous. &quot;See ADR-0003&quot; is a complete reference.</p>
<p><strong>Git is the infrastructure.</strong> ADRs are committed to the repository. The immutability of a decided ADR is preserved through Git history: you can always see what was decided, when, and what changed.
Tags in the frontmatter let you slice context by domain:</p>
<pre><code class="language-yaml">tags: [adr, auth, database]
</code></pre>
<p>The <code>adr</code> tag is what tooling uses to find ADRs. Domain tags let you load only the relevant slice for a given session.</p>
<h4>Writing it</h4>
<p>Start with the problem, not the solution. What gap or situation made this decision necessary? If you can't explain the context, the decision will look arbitrary, to a future reader and to an agent building from the system.</p>
<p>Fill in &quot;What was ruled out&quot; even if the answer felt obvious. &quot;We considered X but ruled it out because Y&quot; is information that prevents the same conversation from happening again.</p>
<p>Keep the rationale close. Put the why immediately after the what. The reader — human or AI — should never have to scroll to understand why something was decided.</p>
<p>Consequences are not optional. What needs to change? What's now true that wasn't before? A decision without consequences documented is half an ADR.</p>
<h4>AI as a thinking partner</h4>
<p>The decision is yours — AI helps you think it through and write it down.</p>
<p>Load your prior ADRs as context before the session. Describe the problem: the gap, the constraints, what you've considered. Use AI to pressure-test your reasoning before you commit. Once you've landed on the decision, ask it to write the ADR. With prior ADRs in context, it already has the format and the system's history. The output is usually close to final.</p>
<h3>Reviewing</h3>
<p>Two checks happen before the ADR is decided.</p>
<p><strong>AI review against prior ADRs.</strong> With prior ADRs loaded as context, ask AI to validate the draft:</p>
<ul>
<li>Is anything missing — rationale, consequences, alternatives that should be named?</li>
<li>Does this supersede something? If it does, that has to be named explicitly in the Context section.</li>
<li>Does this conflict with anything? Every conflict must be resolved in the ADR itself — not in a comment or a conversation.</li>
</ul>
<p><strong>Peer review.</strong> Push the draft as a PR. Use the review process you already have.</p>
<h3>Merging makes it available</h3>
<p>When the PR merges, the decision is made. The ADR joins the history. The anchor is updated.</p>
<p>From this moment the context is live — available to every developer, every agent, every automated workflow that builds from the system. Not because anyone loaded it manually. Because it exists, in the repository, part of the record.</p>
<p>How you make that context reachable to agents at runtime is a tooling question — covered in Part 2.</p>
<h2>The context in use</h2>
<p>The context built above doesn't sit idle. Work is happening continuously — a developer building locally, an agent picking up a Linear ticket, another responding to an incident, a PM triggering something from Slack. All of it is building against your system.</p>
<p>What matters is that when this work happens, the architectural context is available. Not in response to a specific ADR being written. Not only when a human manually loads it. Just available — for any work, at any moment, triggered by anything.</p>
<p>The &quot;write an ADR then immediately implement it&quot; scenario is one case, and it's a small one. The more important case is the ambient one: work is always happening from many directions, and the context is what keeps all of it coherent.</p>
<h3>Making the context accessible</h3>
<p>How you make the context available depends on the kind of work happening.</p>
<p>For a manual session — a developer opening a Claude session to build something — load the ADR history before you start:</p>
<pre><code class="language-bash">npx @nbaglivo/ctx --tags adr --output .claude-context.md
claude --system-prompt-file .claude-context.md
</code></pre>
<p>For agents operating at runtime — responding to events, picking up tickets, executing autonomously — the context needs to be queryable without anyone manually loading files. Tools that expose your ADR history to agents at runtime are crucial here: they allow any agent, at any moment, to access the architectural context before acting. How you provide that depends on your setup. What matters is that the context is reachable — not locked in a file someone has to remember to load.</p>
<h3>Plan, then build</h3>
<p>Before any code is written, a plan should exist. That plan should be checked against the architectural context.</p>
<p>This doesn't have to be a human reviewing a plan. An agent can generate a plan. Another agent can review it against the ADRs. A human can review it. All of these are valid — and in an agentic workflow, they can all happen in sequence. What matters is that the check happens before execution, not after.</p>
<p>The question at the plan stage is always the same: does this align with the decisions that are already in place? The context is what makes that question answerable.</p>
<p>If the plan diverges from the ADRs, correct it here. A conversation costs less — in time and in tokens. Undoing code costs both.</p>
<h3>Your full toolkit still applies</h3>
<p>The ADR context tells agents where the code lives architecturally — the decisions, the constraints, the reasoning. It doesn't replace the rest of your toolkit. Coding standards, skills, rules, MCPs — all of that still applies alongside it.</p>
<p>Your standards tell agents <em>how</em> to write code. The ADRs tell <em>why</em> in that way. Both need to be present. The ADRs are the part that's usually missing.</p>
<p>Setting the anchor and keeping the context in use is the mechanism. What it earns you over time — the compounding effect, when to automate, how the tooling around it evolves — is <a href="https://engineering.nbaglivo.dev/writing/anchored-agentic-development-part-2.html">Part 2: The payoff</a>.</p>
<p>Reach out at <a href="mailto:hi@nbaglivo.dev">hi@nbaglivo.dev</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Bootstrapping ADRs when you have none</title>
      <link>https://engineering.nbaglivo.dev/writing/bootstrapping-adrs-when-you-have-none.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/bootstrapping-adrs-when-you-have-none.html</guid>
      <pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>The previous previous post assumed you already have ADRs. If you're starting a greenfield, great — you can adopt them from day one and the workflow applies immediately. Or maybe you've been really diligent and your existing system is already well documented.</p>
<p>But most systems aren't like that. Most systems have history that was never written down. Decisions got made in Slack threads, in calls that weren't recorded, in someone's head that's no longer at the company. The code is what it is, and nobody fully remembers why.</p>
<p>If that's where you are, the workflow still applies. You just need one extra step: extracting the knowledge before you can organize it.</p>
<h2>You're not starting from zero</h2>
<p>The temptation when you don't have ADRs is to think you have nothing. That's not true.</p>
<p>You have the code. You have a wiki or a Notion, probably half-maintained. You have tickets, PRs, old Slack conversations if you're willing to dig. And you have your own memory — which is underrated as a source, even if it's imperfect.</p>
<p>The knowledge exists. It's just scattered across different stores, in different shapes, with varying levels of reliability. The goal isn't to create knowledge, it's to surface it and give it a better form.</p>
<h2>Strategies for extraction</h2>
<p><strong>From the codebase</strong> Ask Claude to read a specific part of the system and infer the decisions behind it. Not &quot;explain this code&quot; — that gives you a description. Ask &quot;what design decisions does this code reflect? What tradeoffs does it suggest were made?&quot; You'll get a rough draft of the reasoning that shaped it. It won't always be right, but it's a starting point you can correct.</p>
<p><strong>From your wiki, Notion, etc</strong> Dump the relevant pages into context and ask Claude to identify decision patterns — things that look like they were choices, not just descriptions. Pages that say &quot;we use X&quot; are interesting. Pages that say &quot;we use X because Y&quot; are gold. Even partially documented reasoning is worth pulling out.</p>
<p><strong>From your own head</strong> This one is underused. Sit down with Claude and just explain the system out loud — how it works, what the tricky parts are, what you'd do differently. Treat it like onboarding a new engineer. At the end, ask Claude to write ADRs based on what you described. You'll be surprised how much comes out of a 30-minute conversation that you never thought to write down.</p>
<p><strong>From PRs and tickets</strong> If your team has a habit of explaining decisions in PR descriptions or ticket comments, that's a surprisingly rich source. Grep for the why — merge commits, long PR discussions, tickets with acceptance criteria that hint at constraints.</p>
<p>None of these sources are perfect. The point is to triangulate: use multiple sources, let Claude synthesize, and then review and correct. The first output won't be accurate. That's fine.</p>
<h2>The first sessions will feel thin</h2>
<p>This is worth saying clearly: the first few sessions after you start bootstrapping will feel less productive than you expect.</p>
<p>That's not the system failing. That's what it feels like to work with incomplete context. Claude will make suggestions that don't quite fit, miss constraints you know exist, or propose things you've already ruled out. It's frustrating.</p>
<p>Push through it. Every time Claude gets something wrong, that's information — there's a decision that isn't captured yet. Write it down. Add it to an ADR. The next session will be a little better. The one after that will be better still.</p>
<p>The feedback loop from the first post applies here too, just more visibly. When context is thin, the gaps are obvious. That's actually useful — it forces the captures you'd otherwise skip because &quot;everyone knows that.&quot;</p>
<h2>A word on immutability</h2>
<p>ADRs are normally immutable. The idea is that if you want to change a decision, you don't edit the old ADR — you write a new one that supersedes it. That creates a paper trail: you can see what was decided, when, and why it changed.</p>
<p>It's a good rule. For a forward-operating team, it matters.</p>
<p>But when you're backwards-constructing ADRs from an existing system, applying that rule strictly gets in the way. You'll write an ADR, then realize you got the reasoning slightly wrong, then feel like you need to create a superseding ADR for a decision that wasn't really changed — just better understood.</p>
<p>My suggestion: relax the rule until you have a stable set. Let yourself edit, revise, and correct while you're in bootstrap mode. Treat the ADRs as living documents until they settle. Once you feel like the captured decisions accurately reflect how the system actually works and why, that's when you start applying immutability going forward.</p>
<p>The spirit of the rule is to preserve decision history. You can't preserve history you never captured in the first place. Get it captured first, then go immutable.</p>
<h2>Where this leaves you</h2>
<p>There's no clean starting point with a legacy system. You start messy, you iterate, and at some point you cross a threshold where the context is good enough to be genuinely useful.</p>
<p>Once you're there — once Claude has a working mental model of why the system is the way it is — the workflow from the previous posts applies in full. New decisions get made with that context loaded. New ADRs get written from those sessions. The model gets better over time. That full workflow is written up in <a href="https://engineering.nbaglivo.dev/writing/anchored-agentic-development.html">Anchored Agentic Development</a>.</p>
<p>The bootstrapping phase is just the cost of entry for systems that weren't built with this in mind from the start. It's worth paying.</p>
<h2>A reality check</h2>
<p>Your ADRs won't be perfect, and you need to review them. If you solely ask agents to derive decisions from code, you'll end up with hallucinated decisions that were never made, with justifications that nobody ever gave. You'll need to invest time and resist the temptation of delegating. It is better to accept that a decision's rationale was lost, or that a decision was never consciously made and just happened, than to invent (or let an agent invent) fake reasons that might impose unnecessary restrictions.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Giving Claude architectural memory</title>
      <link>https://engineering.nbaglivo.dev/writing/giving-claude-architectural-memory.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/giving-claude-architectural-memory.html</guid>
      <pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate>
      <description>The why, not just the what</description>
      <content:encoded><![CDATA[<p>In the <a href="https://engineering.nbaglivo.dev/writing/context-is-a-choice.html">previous post</a> I described a system for feeding Claude curated context - tagged markdown files loaded via <code>--system-prompt-file</code>. That works well for personal context: how I write, what I'm applying for, what I care about in a given session. But there's another application I find even more useful: giving Claude deep, accurate knowledge of a specific codebase or service, without ever pointing it at source code.</p>
<p>The context source here is ADRs - Architecture Decision Records. I'll use <a href="https://ctx.nbaglivo.dev" target="_blank" rel="noopener noreferrer">ctx</a> to load them throughout this post, but that's just convenience. Any method works. How you get the ADRs in front of Claude is up to you.</p>
<h2>What ADRs are and why they're the right unit</h2>
<p>An ADR is a short document that captures a single architectural decision: what was decided, why, and what alternatives were considered. They're not documentation of how the system works today - they're documentation of why it works the way it does. That distinction matters a lot when you're using them as Claude's context. Source code tells Claude what is happening. ADRs tell Claude why. And when you're asking Claude to help you make a new decision, or implement something consistent with past ones, the why is almost always what it needs. &quot;We use Neon instead of Supabase because of IPv4 connectivity issues on Vercel's serverless runtime&quot; is the kind of sentence that changes the shape of every suggestion Claude makes about the database layer. You can't get that from reading the schema.</p>
<p>There's another dimension to this that matters in practice: ADRs can reflect decisions that haven't been fully implemented yet. Maybe you decided on an approach but only partially built it. Maybe you made a deliberate tradeoff - knowing something wasn't ideal - and documented it, but the code doesn't reflect the intent yet. Maybe life just got in the way. In those cases, the code is a misleading source of truth. It shows you where things are, not where they're going. An ADR that says &quot;we decided to move away from X, migration is ongoing&quot; is more useful to Claude than reading code that still has X in it. Claude won't suggest doubling down on something you've already decided to move away from. It won't treat a temporary workaround as a pattern worth following. The decision document is the intention; the code is just the current state of execution.</p>
<p>ADRs are also naturally scoped and self-contained. Each one covers exactly one decision. That makes them ideal as ctx-tagged files - you can compose a precise context set by pulling just the decisions relevant to the task at hand.</p>
<h2>The tagging structure</h2>
<p>Each ADR lives as a markdown file with frontmatter:</p>
<pre><code>---
tags: [cvmd, auth, database]
title: &quot;ADR-0002: PostgreSQL on Neon&quot;
---
</code></pre>
<p>I tag by service and by domain. cvmd is the service tag - it pulls everything about the system. Domain tags like auth, database, or deployment let me narrow further when I only need a slice. In practice I usually start broad:</p>
<pre><code>npx @nbaglivo/ctx --tags cvmd --output .claude-context.md
claude --system-prompt-file .claude-context.md
</code></pre>
<p>That gives Claude the full architectural picture of the service before I type anything. If the session is tightly scoped - say, only touching auth - I'll filter further:</p>
<pre><code>npx @nbaglivo/ctx --tags cvmd --tag auth --output .claude-context.md
</code></pre>
<h2>What Claude can do with this</h2>
<p>I ran a session with only three ADRs loaded for cvmd.sh - nothing else, no source code, no schema, no running system - and asked detailed questions about the service. It answered accurately. Not approximately, not plausibly - accurately. It knew that schema migrations live under supabase/migrations/ even though Supabase is no longer the database host, because the ADR documented that legacy detail explicitly. It knew the exact shape of the auth migration: what was replaced, what the before/after looked like, and the key design choice that login and GitHub access are separate flows. That's not Claude being clever. That's Claude having good context. The practical implication is that you can have a conversation with Claude about a service as if you were pairing with someone who had read every decision document carefully. You can ask &quot;what would break if we changed X&quot; or &quot;how does Y work&quot; and get answers grounded in the actual reasoning behind the system, not generic suggestions.</p>
<h2>Authoring new ADRs through the same session</h2>
<p>The other half of this - and where it gets genuinely useful - is using the same session to write new ADRs. When I'm working through a new decision, I'll often think it through with Claude first. Claude already has all the prior decisions loaded, so its suggestions are constrained by the system's actual history. It knows what database we use, why we chose it, what we migrated away from. When I ask &quot;how should we handle X&quot;, the answer comes from that context.</p>
<p>Once I've landed on a decision with Claude´s assistance, I ask Claude to write the ADR. It already has the right format from the existing ones in context, and it already understands the decision we just made. The output is usually close to publishable. Then that new ADR gets tagged and committed. The next session is smarter than this one.</p>
<p>Once the ADR exists, it becomes a clear, approved actionable item for AI to build against. You've already made the decision - Claude's job is now implementation, not invention. There will always be implementation details that emerge during the build, but those are details, not direction. The architecture won't drift because the direction is written down and Claude is working from it.</p>
<p>The place to catch any drift is as early as possible. You can catch it during planning - before a single line is written - by asking Claude to walk through its approach against the ADR. Or you can catch it during review, but by then a considerable amount of tokens have already been spent going the wrong way, and you're making corrections instead of preventing them. The whole point of this process is to shift that left: agree on the decision first, document it, then build. The ADR is the checkpoint that happens before the build starts.</p>
<h2>The prompting pattern</h2>
<p>A few things I've found that make this work better: Be explicit about what you want Claude to do with the context. &quot;You have the architectural context for this service. I want to implement X - tell me what to build and flag anything that conflicts with existing decisions.&quot; That framing activates the context differently than just describing the task.</p>
<p>Ask Claude to surface conflicts. &quot;Does this decision contradict anything in the existing ADRs?&quot; is a genuinely useful question when Claude has all of them loaded. It will catch things you won't.</p>
<p>Use the session to think, then commit the output. The session is ephemeral. The ADR is permanent. The habit of ending a session by asking Claude to write the decision document means that nothing gets lost - the thinking becomes a record.</p>
<h2>Why pairing a tool like ctx and ADRs works</h2>
<p>ctx is really just a way of choosing what gets loaded. ADRs are a way of making architectural knowledge portable and composable. Together they mean Claude can show up to a session with a specific, accurate mental model of your system - not the whole codebase, not a vague summary, but the decisions that shaped it. That's a different kind of AI assistance than generating boilerplate or explaining syntax. It's closer to having a collaborator who has read everything you've ever decided about the system and can reason from it.</p>
<h2>This wasn't planned</h2>
<p>I didn't set out to write a series. The first post was just me documenting a system I'd built for myself. Then I realized the ADR use case was a different enough application that it deserved its own post. And now here we are.</p>
<p>What's becoming clear is that there's a coherent thread running through all of this: using structured, curated text to give Claude an accurate model of something - your writing style, your job search, your service's architecture. The tool is the same. The context sources are different.</p>
<p>Next, I want to explore what happens when you let that architecture breathe - when you take the decisions that have accumulated in your ADRs and use AI to help visualize the system that emerges from them. How do you see the whole when it's been built decision by decision? That's what <a href="https://engineering.nbaglivo.dev/writing/anchored-agentic-development.html">Anchored Agentic Development</a> gets into.</p>
<p>And further down the line, I want to talk about human participation in this process - how this stops being a solo workflow and becomes a team one. Everything I've described so far is one person and one AI. But ADRs were always meant to be a team artifact, and there's an interesting question about how the context, the decisions, and the AI assistance scale when more people are involved. That's a later chapter.</p>
]]></content:encoded>
    </item>
    <item>
      <title>AI anxiety is a systems problem, not a people problem</title>
      <link>https://engineering.nbaglivo.dev/writing/ai-anxiety-is-a-systems-problem-not-a-people-problem.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/ai-anxiety-is-a-systems-problem-not-a-people-problem.html</guid>
      <pubDate>Fri, 10 Apr 2026 00:00:00 GMT</pubDate>
      <description>The role that turns it into organizational capability</description>
      <content:encoded><![CDATA[<p>A colleague told me recently he was experiencing what he called AI job anxiety.</p>
<p>He's trying to use AI. He's experimenting with different things. But he also has a job to do, with real deliverables and real expectations. And right now, AI is actually slowing him down — because he's still in the learning curve, still figuring out what works, and that takes time he doesn't really have.</p>
<p>On top of that, the company is pushing for AI adoption. Paying for tokens, encouraging usage, signaling that it matters. So there's pressure from that direction too. And when he looks around, he sees colleagues trying new tools, sharing discoveries, and experimenting with things he hasn't even heard of. This makes him feel like he should be doing the same. But he doesn't have the bandwidth. And honestly, he's not particularly excited about AI as a topic — it's not his thing. It doesn't light him up the way it does for some people.</p>
<p>And then there's the world. Job postings that list AI fluency as a requirement for roles that had nothing to do with AI a year ago. Products wrapping everything in AI features. Social media where if you're not actively experimenting with the latest model or tool, you're already behind. The message is constant and hard to ignore: get on board or become irrelevant, a dinosaur... we know what happened to the dinosaurs.</p>
<p>So you have someone who feels behind, who's losing time while trying to save it, who's pushed from every direction to experiment but has no space to do it, and who carries none of the intrinsic motivation that would make any of this feel worthwhile. That's the anxiety. It makes sense.</p>
<p>And to be clear — this person is capable. He's not checked out, not avoiding it, not failing to try. It's just that AI is a genuinely new field that moves extremely fast. Things that were true six months ago aren't true anymore, you know: &quot;MCPs are great. MCPs are dead. MCPs are great again&quot;. New tools, new models, new patterns, competing opinions. Keeping up with all of that is itself a job. Doing it while also doing your actual job is a lot to ask of anyone.</p>
<p>The anxiety isn't a character flaw. It's a reasonable response to an unreasonable amount of change.</p>
<p>Now multiply that across a team.</p>
<p>Everyone is going through some version of the same thing — at different speeds, with different levels of enthusiasm, in different directions. Someone finds a useful technique and mentions it in a Slack thread. A few people see it. Most don't. Nothing gets written down in any durable way. The next person discovers the same thing two weeks later and the cycle repeats.</p>
<p>The organization is paying the learning cost over and over again — once per person — and capturing almost none of it. The knowledge exists, scattered across individuals and conversations and half-remembered experiments. But it doesn't compound. It just evaporates.</p>
<p>That's not a people problem. It's a systems problem. And it's solvable.</p>
<p>What my colleague actually needs isn't more time to experiment. It's someone who has already done the experimenting for him.</p>
<p>Someone who has made it their job to stay on top of the landscape — not because they have to squeeze it in between other responsibilities, but because that is the responsibility. Someone who filters the noise, forms opinions, figures out what's worth adopting and what can wait, and then brings that back to the team in a usable form. Not a newsletter. Not a talk. Something actionable — a pattern, a system, a tool, a guideline.</p>
<p>With that person in place, the dynamic changes completely. The capable engineer who was drowning in anxiety doesn't need to figure it all out himself anymore. He can trust that someone is handling that layer. He stays focused on delivering. He picks up the relevant pieces when they're handed to him, already digested. His productivity goes up. His anxiety goes down. And the organization captures the learning once, not twelve times.</p>
<p>That's the role I've been thinking about. I don't have a clean name for it yet — but I know what it does.</p>
<h2>Staying ahead so the team doesn't have to</h2>
<p>The first direction is about working practice. How does the team use AI well, day to day?</p>
<p>This sounds simple but it isn't. Using AI effectively isn't just a matter of having access to a model. It's knowing how to give it the right context. Knowing when to trust the output and when to push back. Knowing which tools are worth the switching cost and which ones aren't ready yet. That knowledge takes time to develop — time most people don't have.</p>
<p>Someone in this role develops it deliberately. They experiment, they form opinions, they stay current not as a hobby but as the job. And crucially, when they find something that works, they don't just use it themselves. They turn it into something the whole team can use. A shared system. A guideline. A small tool. Something that makes the right behavior the easy behavior, for everyone.</p>
<p>That last part matters. Insight that stays in one person's head doesn't scale. The output of this work should be transferable — something that outlasts any single session or conversation.</p>
<h2>Teaching AI as a building block</h2>
<p>The second direction is different. It's less about how engineers work and more about what they build.</p>
<p>Product engineers need enough understanding of AI to use it in features and products. That means knowing how to connect to a model, how to structure a prompt for reliability, how to think about testing something that's probabilistic. When to reach for AI as part of a solution and when it's the wrong tool entirely. What the real trade-offs are, not the marketing version.</p>
<p>Someone in this role develops guidelines, runs sessions, and sometimes sits directly inside a project as the AI expert — not to own the implementation, but to make sure the team is building on solid ground. The goal isn't to become the person who does all the AI work. It's to make everyone else capable of doing it well.</p>
<h2>What this looks like in practice</h2>
<p>The ctx series I've been writing is a small but good concrete example of both pillars at work. ctx is a small CLI tool for managing context in Claude sessions — the idea being that instead of Claude receiving everything you've ever written down, you curate exactly what's relevant to the session at hand, using tagged markdown files that you compose on the fly.</p>
<p>It started with a real problem: Claude was getting the wrong context, or too much of it. The knowledge existed — in markdown files, in ADRs, in notes — but there was no good system for deciding what to surface when.</p>
<p>Working through that problem produced two things. A system — tagged markdown files, a generation step, a way of thinking about context as something intentional and composable. And a tool — a small CLI that makes the system frictionless enough to actually use. Something any engineer on the team can pick up without having to reconstruct the thinking behind it.</p>
<p>That's the shape of this work. Someone thought carefully about how to get more out of AI, built something that encodes that thinking, and made it available to everyone. The team gets the benefit without each person having to rediscover it independently.</p>
<p>I still don't have a perfect name for this.</p>
<p>Most organizations hiring for AI right now are hiring to build AI into their products — engineers who can work with models, build pipelines, ship AI-powered features. That's legitimate and necessary. But it's a different problem. The internal capability question — how does the whole team get better at using AI — often goes completely unaddressed.</p>
<p>Sometimes someone champions it informally and something useful emerges. But that's fragile. It depends on the right person happening to be there, having the space, and caring enough to do it on top of everything else. That's not a strategy. It's luck. And it produces exactly the kind of scattered, non-compounding knowledge that got us to the Slack thread problem in the first place.</p>
<p>This should be something organizations make happen deliberately, through a role that owns it — not something they hope will organically emerge.</p>
<p>The closest analogy I keep coming back to is platform engineering. The mindset is the same: don't make every team solve the same problem independently. Build the internal capability that makes everyone faster, more reliable, and less likely to reinvent the wheel.</p>
<p>So maybe that's what it ends up being called. AI Platform Engineer. It's not perfect. But it points in the right direction.</p>
<p>The case for this role isn't only about efficiency, though that case is real. It's also about the people inside the organization. The anxiety my colleague described is widespread. Nobody should feel like a dinosaur for not having kept up with a field that moves this fast while also doing a full-time job. That's not a reasonable standard to hold people to.</p>
<p>The role exists to make the situation more humane — to absorb a burden that's currently distributed across everyone, and concentrate it somewhere it can actually be handled well. That's better for the organization. But it's also just better for the people in it.</p>
<p>There's a talent angle here too. Engineers who are excellent at what they do — and who care about staying sharp — are thinking about this. They want to grow. They want to work somewhere that takes the craft seriously, including what AI means for it. A company that has figured out this function is signaling something: we're not leaving you to drown in the noise alone — we're investing in making you better. That's genuinely attractive. Not just for retention, but for the kind of people you want to hire in the first place. The best engineers have options. They'll choose the environment where they can do their best work — and where staying relevant doesn't feel like a second job.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Context is a choice</title>
      <link>https://engineering.nbaglivo.dev/writing/context-is-a-choice.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/context-is-a-choice.html</guid>
      <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
      <description>Why curating Claude's context matters more than expanding it</description>
      <content:encoded><![CDATA[<p>I keep a repo of markdown files that I use as context for Claude. Notes about how I write, project details, decisions I've made and why, things I want Claude to know about me so I don't have to re-explain them every session. It works well. Until it doesn't. The problem showed up when I started adding job-hunting material - cover letter drafts, notes about specific companies, salary expectations, the whole thing. Suddenly that information was leaking into unrelated sessions. I'd be thinking through a technical essay and Claude would have all that hiring context loaded for no reason. It felt noisy. And a little weird. What I wanted was simple: one repo, all my notes, but a way to tell Claude which context to use for a given session. Job hunting context when I'm writing applications. Essay-thinking context when I'm drafting technical pieces. Writing preferences always.</p>
<h2>How Claude Code loads context</h2>
<p>Claude Code looks for a <code>CLAUDE.md</code> file at the root of your repo and loads it automatically. You can also pass a <code>--system-prompt-file</code> flag at invocation time, which lets you supply an arbitrary file as the system prompt for that session. That second option is the lever I wanted. It means I can generate a context file on the fly, pass it in, and Claude gets exactly what I decided - nothing more.</p>
<h2>The system</h2>
<p>Each markdown file in my contexts/ folder has a small frontmatter block:</p>
<pre><code>---
context: job-hunting
title: Active Applications
---
</code></pre>
<p>Some files are tagged global - writing preferences, general notes about how I think. Those always get included. Everything else is opt-in by tag. A small TypeScript script, ctx, reads those files, filters by the requested tag, and writes a single .claude-context.md file:</p>
<pre><code>ctx job-hunting      # global + job-hunting files
ctx essay-thinking   # global + essay-thinking files
ctx                  # global only
</code></pre>
<p>Then I run Claude with that file as the system prompt:</p>
<pre><code>claude --system-prompt-file .claude-context.md
</code></pre>
<p>I have a shell alias that chains both steps so it's just <code>ctx job-hunting</code> and Claude opens with the right context loaded. The generated file is gitignored. It's ephemeral by design - the source markdown files are the truth, the generated file is just today's lens into them.</p>
<h2>The virtuous cycle</h2>
<p>But here's the thing that makes this system actually grow: when I finish a writing session and realize Claude was missing something - context that would've made the conversation better - I ask Claude to rewrite my context files to include it. That gap becomes a patch. Over time, my context repo gets richer and more useful without me having to manually maintain it. The system learns from what it was missing. It's a small feedback loop, but it compounds. Each session that reveals a gap also enriches the next one.</p>
<h2>The tradeoff worth knowing</h2>
<p>Everything in a system prompt gets counted as tokens on every message in the session. That's different from how CLAUDE.md works, where Claude can be more selective. So if your context files grow large, you'll feel it in cost and (marginally) in speed. The script prints a rough token estimate when it runs, which is a good habit to build. My current contexts are small enough that it doesn't matter. But it's the kind of thing that quietly gets expensive if you stop paying attention.</p>
<h2>The tool that makes this frictionless</h2>
<p>To be clear: the system doesn't depend on any particular tool. You could do this manually - write a merged markdown file by hand, paste the right pieces together, pass it to Claude. The concept works regardless. What a tool buys you is removing the friction between &quot;I want job-hunting context&quot; and Claude actually having it. I built a small CLI for exactly this: ctx. You install it once, tag your markdown files with YAML frontmatter, and then it's:</p>
<pre><code>npx @nbaglivo/ctx --tag job-hunting --output .claude-context.md
</code></pre>
<p>It scans your notes directory, matches everything tagged job-hunting, merges them into a single file, and tells you how much it wrote. Then you pass that file to Claude as the system prompt. That's the whole thing. The reason I bothered packaging it is that the manual version has just enough friction to make you skip it. And skipping it means Claude gets the wrong context, or too much context, or you spend the first five minutes of a session re-explaining things you've already written down. The tool makes the right behavior the easy behavior.</p>
<h2>Why this feels right</h2>
<p>There's something clarifying about making context explicit and intentional. Before this, my context repo was growing into a single blob of everything-about-me. Now it has structure that reflects how I actually think about different modes of work. Tagging a file job-hunting isn't just a filter instruction - it's an acknowledgment that this information has a scope. It's relevant here, not everywhere. That's just good information hygiene, and it's nice when the tooling reflects it. The whole thing is maybe 80 lines of TypeScript and a naming convention. Most good systems are.</p>
]]></content:encoded>
    </item>
    <item>
      <title>My hopes for AI</title>
      <link>https://engineering.nbaglivo.dev/writing/my-hopes-for-ai.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/my-hopes-for-ai.html</guid>
      <pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>A lot of the excitement and the hype around AI producing code, particularly at the C-levels of the world, comes in some flavor of &quot;Imagine how productive we can be&quot; — some might mean, &quot;imagine how much money we can save&quot; — and certainly there are reasons to believe that AI will completely take over coding in the near future, there are also reasons to believe it is just a bubble, that AI is helpful until it isn´t, and that at least this attempt at AI will never be capable of creating a real, complex production system that is truly maintainable and capable of growing, we have all experienced that when vibe coding stops being fun and turns into a debugging nightmare.</p>
<p>I certainly hope AI does fulfill its promise of managing to create these systems, but not because I want to save money or become more productive, but because I believe it will unlock new possibilities for Humans to come back to what I believe makes us humans: Creativity. I don´t think productivity is an inherent human need or trait, I think creativity is, and it is core to the experience of being a human being, we don´t need to be productive at being creative, we just need to be, but in a world with so many distractions and so much demand for executing, for performing, we often disconnect from our creativity and put our energy at the service of other things.</p>
<p>I also hope AI gives us more free time, that this need for being productive and performant goes away and enables us to just wander outside, because when we physically wander, our mind also starts wandering, and that´s also when creativity comes to us, like when you were trying to come up with a solution for something the whole day just to get an incredible novel solution randomly while showering.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Why Product Engineers are the most valuable asset for leaders in the AI era</title>
      <link>https://engineering.nbaglivo.dev/writing/why-product-engineers-are-the-most-valuable-asset-for-leaders-in-the-ai-era.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/why-product-engineers-are-the-most-valuable-asset-for-leaders-in-the-ai-era.html</guid>
      <pubDate>Tue, 08 Oct 2024 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>There are many types of software engineers, but those with a product mindset, who understand outcomes and value, are by far the most valuable to your organization.</p>
<p>Engineers often share a passion for problem-solving, but many focus solely on solving problems without considering the significance of the problem itself. These engineers might excel at finding solutions, but they might not care about the context, leading them to solve issues that don't contribute meaningfully to the organization's goals. While these individuals are valuable and play an important role, they won't bring the kind of transformative value that can change the game.</p>
<p>So, who will? The engineers who make the biggest impact are those who care as much about the problem being solved as they do about the solution itself. These engineers draw energy from understanding the broader objectives, beyond merely implementing something. They strive to create real value and effect change in the world — or at least in the areas they can influence. These individuals are product engineers, a rare blend of passion for technology, problem-solving ability, and a deep understanding of the impact they want to make. They are outcome-oriented, not just output-driven. They focus on solving real issues, not just on using the latest shiny technology, and they get excited about contributing to the greater good, not just about their next puzzle to solve.</p>
<p>If you are a leader and you find one of these people, nurture them. Put them in positions where they can understand the bigger picture, the outcomes the organization is trying to achieve, and the needs of stakeholders. Involve them early in the discovery phase, where they can contribute their technical expertise. They won't just save you from designing solutions that later prove unfeasible within constraints like budget and time; often, they are the key to creating enabling technology. Empower these individuals by placing them alongside key product people, such as product managers and product designers.</p>
<p>And if you are one of these product engineers, know that you are incredibly valuable. Seek out environments where you can grow and make a significant impact. Don't hesitate to change teams or companies if necessary. Problem-solving might be the first thing AI takes over, but creating innovative products — that's something else entirely. This is your opportunity: leverage AI to solve technical challenges, and focus on designing solutions that are not only technically feasible and exciting but also aligned with the outcomes your organization aims to achieve.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Rethinking the Role of Tech Leadership</title>
      <link>https://engineering.nbaglivo.dev/writing/rethinking-the-role-of-tech-leadership.html</link>
      <guid isPermaLink="true">https://engineering.nbaglivo.dev/writing/rethinking-the-role-of-tech-leadership.html</guid>
      <pubDate>Sun, 08 Jan 2023 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>In today's rapidly evolving tech landscape, the role of leadership is not just about overseeing the development of technologies but about fostering an environment where communication and collaboration shape the system architecture. This approach acknowledges Conway's Law, which suggests that organizations design systems that mirror their own communication structures.</p>
<p>Leadership in technology should focus on crafting the right teams for the right missions, allowing these teams to organically develop solutions that align with the overarching mission of the organization. This is a shift from a traditional approach where leadership might dictate specific services and architectures. Instead, tech leaders should enable teams by defining their purposes and ensuring they have the tools and support necessary to succeed.</p>
<p>A practical application of this philosophy is seen in the use of Objectives and Key Results (OKRs). OKRs empower teams to own their strategies and align their efforts with the broader company goals. This autonomy is crucial. When teams are merely handed down projects without involvement in the architectural decisions, they are less likely to feel accountable or invested in the outcomes. True ownership requires that teams have the freedom to make both product and software decisions.</p>
<p>Supporting teams goes beyond just setting goals; it involves continuous engagement to help them navigate challenges and reduce cognitive overload. This might involve establishing specialized teams, such as platform teams or enabling teams, which help streamline processes and allow product teams to focus on their core missions without getting bogged down by technical redundancies.</p>
<p>However, leadership's role isn't just in facilitation and support. It's also about maintaining the health of the team dynamics, identifying when teams are overwhelmed, and adjusting team structures or missions to prevent burnout and ensure productivity. This proactive engagement helps preserve the agility and responsiveness of the organization.</p>
<h2>Leadership Missteps to Avoid</h2>
<p>Tech leadership should avoid the pitfalls of 'Ivory Tower' architecture, where decisions are made in isolation from those who implement them. Such approaches can lead to disconnection, dissatisfaction, and ultimately, dysfunction within teams. Instead, leadership should cultivate architectural skills within teams, encouraging them to design solutions that are best suited for their specific challenges.</p>
<p>In summary, the role of tech leadership today is to design ecosystems of communication and collaboration, rather than dictating technical specifics. By doing so, they not only leverage the collective expertise of their teams but also drive innovation and ownership that are critical for the success of modern tech organizations.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
