<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.domfarr.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.domfarr.com/" rel="alternate" type="text/html" /><updated>2026-04-23T15:41:10+00:00</updated><id>https://www.domfarr.com/feed.xml</id><title type="html">Dominic Farr</title><subtitle>Platform Architecture for Regulated and Agentic Systems</subtitle><author><name>Dominic Farr</name></author><entry><title type="html">Strands or LangChain: a simple rubric</title><link href="https://www.domfarr.com/2026/04/23/strands-vs-langchain-rubric.html" rel="alternate" type="text/html" title="Strands or LangChain: a simple rubric" /><published>2026-04-23T00:00:00+00:00</published><updated>2026-04-23T00:00:00+00:00</updated><id>https://www.domfarr.com/2026/04/23/strands-vs-langchain-rubric</id><content type="html" xml:base="https://www.domfarr.com/2026/04/23/strands-vs-langchain-rubric.html"><![CDATA[<p>Two Python orchestration tools. Different bets.</p>

<p>LangChain has been the default since 2022. Large ecosystem, integrations for most models and vector stores, active community. If something exists in the LLM space, there is probably a LangChain wrapper for it. That breadth comes with accumulated abstractions — LCEL, LangGraph, chains — and you spend time learning which layer applies before you get to the actual problem.</p>

<p>Strands is AWS’s agent SDK, open-sourced in 2025. The model is simpler: tools are Python functions decorated with <code class="language-plaintext highlighter-rouge">@tool</code>, you point it at a Bedrock model, and the runtime handles the loop. No graph definitions. No chain configuration. A working agent is around twenty lines.</p>

<div style="text-align:center; margin: 2rem 0;">
  <img src="/assets/strands-vs-langchain-rubric.svg" alt="Rubric comparing Strands and LangChain across six dimensions" style="max-width:100%;" />
</div>

<p>The rubric surfaces two clear splits.</p>

<p>Setup speed, agent-first design, and AWS fit all go to Strands. The surface area is small by design. Bedrock is the intended path and it works well if you’re already there.</p>

<p>Model flexibility and ecosystem go to LangChain. Dozens of providers, connectors for most databases and retrieval systems, and LangSmith for tracing. If your stack isn’t AWS or you need integrations Strands doesn’t have, LangChain is the safer choice.</p>

<p>Production simplicity is close. Strands wins on fewer moving parts. LangChain’s observability tooling is better, but it adds setup.</p>

<p>The decision reduces to two questions. Are you AWS-native? Do you need integrations Strands doesn’t cover?</p>

<p>If neither applies, start with Strands. You can always migrate out when you hit the ceiling.</p>]]></content><author><name>Dominic Farr</name></author><category term="agentic" /><category term="python" /><category term="tooling" /><summary type="html"><![CDATA[Two Python orchestration tools. Different bets.]]></summary></entry><entry><title type="html">Stop Thinking About Python Tooling</title><link href="https://www.domfarr.com/2026/04/20/python-tooling-ruff-pyright-uv-pre-commit.html" rel="alternate" type="text/html" title="Stop Thinking About Python Tooling" /><published>2026-04-20T00:00:00+00:00</published><updated>2026-04-20T00:00:00+00:00</updated><id>https://www.domfarr.com/2026/04/20/python-tooling-ruff-pyright-uv-pre-commit</id><content type="html" xml:base="https://www.domfarr.com/2026/04/20/python-tooling-ruff-pyright-uv-pre-commit.html"><![CDATA[<p>Good Python repos in 2026 run <a href="https://docs.astral.sh/ruff/">ruff</a>, <a href="https://github.com/microsoft/pyright">pyright</a>, and <a href="https://docs.astral.sh/uv/">uv</a>. Ruff handles linting and formatting, replacing flake8, black, and isort in one tool. Pyright does static type checking. uv replaces pip and virtualenv and is fast enough that you stop noticing it.</p>

<p>Most teams already know these exist. The issue is remembering to run them.</p>

<div style="text-align:center; margin: 2rem 0;">
  <img src="/assets/git-commit-pre-commit.svg" alt="Git pre-commit hook flow" style="max-width:100%;" />
</div>

<p>A pre-commit hook fires on <code class="language-plaintext highlighter-rouge">git commit</code>, before anything is recorded. Failed check, commit stops. Style problems surface in your working directory rather than CI.</p>

<p>Drop this into <code class="language-plaintext highlighter-rouge">.git/hooks/pre-commit</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/sh</span>
<span class="nb">set</span> <span class="nt">-e</span>
uv run ruff check <span class="nb">.</span> <span class="nt">--fix</span>
uv run ruff format <span class="nb">.</span>
uv run pyright
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">set -e</code> exits on the first failure. <code class="language-plaintext highlighter-rouge">--fix</code> lets ruff correct what it can automatically. Make it executable:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">chmod</span> +x .git/hooks/pre-commit
</code></pre></div></div>

<p>For shared repos, version-control the hooks using <a href="https://pre-commit.com/">pre-commit</a> and a <code class="language-plaintext highlighter-rouge">.pre-commit-config.yaml</code>. Then everyone runs the same checks on every commit without a manual setup step.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">repos</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/astral-sh/ruff-pre-commit</span>
    <span class="na">rev</span><span class="pi">:</span> <span class="s">v0.9.0</span>
    <span class="na">hooks</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">ruff</span>
        <span class="na">args</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">--fix</span><span class="pi">]</span>
      <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">ruff-format</span>
  <span class="pi">-</span> <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/RobertCraigie/pyright-python</span>
    <span class="na">rev</span><span class="pi">:</span> <span class="s">v1.1.390</span>
    <span class="na">hooks</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">pyright</span>
</code></pre></div></div>

<p>Run <code class="language-plaintext highlighter-rouge">pre-commit install</code> once per clone.</p>

<p>The checks run when the commit runs. You stop scheduling them.</p>]]></content><author><name>Dominic Farr</name></author><category term="python" /><category term="tooling" /><category term="automation" /><summary type="html"><![CDATA[Good Python repos in 2026 run ruff, pyright, and uv. Ruff handles linting and formatting, replacing flake8, black, and isort in one tool. Pyright does static type checking. uv replaces pip and virtualenv and is fast enough that you stop noticing it.]]></summary></entry><entry><title type="html">Delivery Processes Are Trust Mechanisms</title><link href="https://www.domfarr.com/2026/02/25/the-processes-we-follow-for-delivering-create-soft.html" rel="alternate" type="text/html" title="Delivery Processes Are Trust Mechanisms" /><published>2026-02-25T00:00:00+00:00</published><updated>2026-02-25T00:00:00+00:00</updated><id>https://www.domfarr.com/2026/02/25/the-processes-we-follow-for-delivering-create-soft</id><content type="html" xml:base="https://www.domfarr.com/2026/02/25/the-processes-we-follow-for-delivering-create-soft.html"><![CDATA[<p>Every gate in your software pipeline exists because someone once asked: how do I know this is safe to ship?</p>

<p>Code review, test coverage, staging environments, deployment approvals. These are trust infrastructure. They encode what your organisation learned from past failures.</p>

<p>Agent-generated code doesn’t change that question. It increases the volume and velocity at which it needs answering.</p>

<p>A team generating code 10x faster through an agent still needs to validate it. If your review process was already shallow — two-minute glances, no checklist, tests written after the fact — you haven’t changed the process. You’ve increased the throughput of it.</p>

<p>Consider a team with inconsistent test coverage and informal review norms. They adopt an agent-assisted workflow. Output doubles within a sprint. Review latency spikes. Reviewers feel the pressure to keep up. A two-second glance and a merge becomes the default. Within two months, defect rates climb and the blame lands on the AI.</p>

<p>The AI didn’t introduce the dysfunction but it dud scaled it.</p>

<p>Teams that adapt well tend to share one characteristic: deliberate validation design before adoption. Structured review checklists. Defined defect classes. Clear ownership of what automated testing covers and what it does not.</p>

<p>They also expect a J-curve. Early adoption slows throughput before it speeds it up. That dip is where trust infrastructure gets stress-tested.</p>

<p>The practical move is to audit your current pipeline before expanding agent usage. Identify where review is weakest. Fix that first. Then scale.</p>

<p>The sequence matters.</p>]]></content><author><name>Dominic Farr</name></author><category term="agentic" /><category term="delivery" /><category term="process" /><summary type="html"><![CDATA[Every gate in your software pipeline exists because someone once asked: how do I know this is safe to ship?]]></summary></entry><entry><title type="html">Your Delivery System Was Designed for a Different Constraint</title><link href="https://www.domfarr.com/2026/02/24/assume-code-becomes-semi-black-box-redesign-delive.html" rel="alternate" type="text/html" title="Your Delivery System Was Designed for a Different Constraint" /><published>2026-02-24T00:00:00+00:00</published><updated>2026-02-24T00:00:00+00:00</updated><id>https://www.domfarr.com/2026/02/24/assume-code-becomes-semi-black-box-redesign-delive</id><content type="html" xml:base="https://www.domfarr.com/2026/02/24/assume-code-becomes-semi-black-box-redesign-delive.html"><![CDATA[<p>Most engineers don’t review transpiled output or minified bundles. They review the source and trust the pipeline. At some point, that output became a black box. Validation moved up a level. Nobody held a ceremony about it.</p>

<p>The same shift is happening with agentic code generation. And most delivery systems haven’t adjusted.</p>

<p>Dave Farley recently explained the Nyquist-Shannon Sampling Theorem in the context of software delivery<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>. To reliably detect change, you must sample at twice the frequency of the change itself. If AI increases code output volume, and humans remain the primary sampling layer, review doesn’t scale. The human becomes the bottleneck by design.</p>

<p>The METR study<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup> found developers using AI tools were 19% slower on average. The code changed. The delivery system didn’t. That mismatch is where the cost accumulates.</p>

<p>So where does validation move?</p>

<p>Three places. Contracts define expected behaviour before anything is written. External test coverage confirms the implementation meets those contracts. Runtime monitoring catches what slips through both. Together, they replace the pull request as the primary quality gate.</p>

<p>Teams on the frontier are already redesigning around this. They’re not reviewing every line of generated code. They’re investing in interface definitions, automated coverage thresholds, and production observability. The checkpoint moved.</p>

<p>If your team’s primary validation mechanism is still a pull request review, that process was built for a world where implementation speed was the constraint. It probably isn’t anymore.</p>

<p>Audit where your validation actually sits. That’s where to start.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p><a href="https://www.youtube.com/watch?v=XavrebMKH2A">https://www.youtube.com/watch?v=XavrebMKH2A</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p><a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Dominic Farr</name></author><category term="agentic" /><category term="delivery" /><category term="testing" /><summary type="html"><![CDATA[Most engineers don’t review transpiled output or minified bundles. They review the source and trust the pipeline. At some point, that output became a black box. Validation moved up a level. Nobody held a ceremony about it.]]></summary></entry><entry><title type="html">The Constraint Has Moved. Most Teams Haven’t.</title><link href="https://www.domfarr.com/2026/02/24/when-code-delivery-is-fully-automated-the-constrai.html" rel="alternate" type="text/html" title="The Constraint Has Moved. Most Teams Haven’t." /><published>2026-02-24T00:00:00+00:00</published><updated>2026-02-24T00:00:00+00:00</updated><id>https://www.domfarr.com/2026/02/24/when-code-delivery-is-fully-automated-the-constrai</id><content type="html" xml:base="https://www.domfarr.com/2026/02/24/when-code-delivery-is-fully-automated-the-constrai.html"><![CDATA[<p>Software delivery has spent thirty years managing human inconsistency. Two developers interpret the same requirement differently. A third forgets an edge case. A fourth ships something untested on Friday. So you built process around it. Standups, sprint reviews, merge gates, retrospectives.</p>

<p>That process was solving a real problem. The problem is changing.</p>

<p>When implementation becomes agentic, you stop managing variance between ten engineers. You’re managing a system that produces consistent output at volume, with failure modes that look nothing like what Jira was designed to track.</p>

<p>The compiler analogy holds here. Nobody reviews compiled bytecode in a pull request. You validate the source, trust the compiler, and monitor runtime behavior. Specification in. Behavior out. You test the contract, not the intermediate steps. Agentic code delivery is heading toward the same model.</p>

<p>Teams already operating near this boundary aren’t running two-week sprints. They’re investing in three things: prompt discipline (what goes in), evaluation frameworks (how correct output is defined), and observability (what happens at runtime). The constraint has moved from writing code to specifying behavior and catching drift when it occurs.</p>

<p>The Scrum Master role was an answer to a specific organisational problem. That problem is dissolving. New ones are forming around specification quality, automated validation, and governance of systems you didn’t write line by line.</p>

<p>Audit your ceremonies against the risks they were built to manage. Some of them no longer apply.</p>]]></content><author><name>Dominic Farr</name></author><category term="agentic" /><category term="delivery" /><category term="process" /><summary type="html"><![CDATA[Software delivery has spent thirty years managing human inconsistency. Two developers interpret the same requirement differently. A third forgets an edge case. A fourth ships something untested on Friday. So you built process around it. Standups, sprint reviews, merge gates, retrospectives.]]></summary></entry></feed>