<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: karl-heinz reichel</title>
    <description>The latest articles on DEV Community by karl-heinz reichel (@karlheinz_reichel_7ee08d).</description>
    <link>https://dev.to/karlheinz_reichel_7ee08d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3220925%2Fbdcde349-db12-472b-a3f5-a412a65e4e6e.jpg</url>
      <title>DEV Community: karl-heinz reichel</title>
      <link>https://dev.to/karlheinz_reichel_7ee08d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karlheinz_reichel_7ee08d"/>
    <language>en</language>
    <item>
      <title>Two Doors, One Gate: Navigating Governance Beyond EDD</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Sat, 27 Jun 2026 22:31:18 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/two-doors-one-gate-navigating-governance-beyond-edd-5clj</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/two-doors-one-gate-navigating-governance-beyond-edd-5clj</guid>
      <description>&lt;h1&gt;
  
  
  Two Doors, One Gate
&lt;/h1&gt;

&lt;p&gt;Onboarding guardrails and power-user friction look like the same problem. They aren't.&lt;/p&gt;

&lt;p&gt;June 2026 · 7 min · Karl-Heinz Reichel&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Setup&lt;/li&gt;
&lt;li&gt;The Category Error We Already Made Once&lt;/li&gt;
&lt;li&gt;Two Layers, Not One Document&lt;/li&gt;
&lt;li&gt;Letting the Data Set the Threshold&lt;/li&gt;
&lt;li&gt;Accountability Instead of a Badge&lt;/li&gt;
&lt;li&gt;Closing Thought&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few weeks ago we wrote about &lt;a href="https://calyntro.com/blog/posts/programming_in_threes/" rel="noopener noreferrer"&gt;why we run AI coding sessions with two developers instead of one&lt;/a&gt;. Triplet programming works well as a transitional structure — a way to build shared fluency while the risk of agent-driven, codebase-wide changes is still high.&lt;/p&gt;

&lt;p&gt;It does not survive contact with forty developers.&lt;/p&gt;

&lt;p&gt;At team scale, you cannot put everyone in a triplet indefinitely, and you should not want to. Some developers arrived at agentic coding only recently. Others are already running skills and multi-agent setups solo and have been for months. The instinct, reasonably, is to write it all down: a &lt;code&gt;CLAUDE.md&lt;/code&gt;, a &lt;code&gt;copilot-instructions.md&lt;/code&gt;, a shared set of rules — &lt;em&gt;plan before you change code&lt;/em&gt;, &lt;em&gt;do not touch files outside the task scope&lt;/em&gt;, &lt;em&gt;explain your reasoning before you act&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We tried exactly that. The result was a document that newer developers needed and barely noticed, and that experienced developers read once, in detail, and immediately wanted to relax.&lt;/p&gt;

&lt;p&gt;That reaction was not impatience. It was the predictable result of asking one document to do two jobs that don't actually fit together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Category Error We Already Made Once
&lt;/h2&gt;

&lt;p&gt;We have actually run into this shape of problem before — just at a different point in the pipeline.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://calyntro.com/blog/posts/2026-05-31-last_mile_problem/" rel="noopener noreferrer"&gt;The Last Mile Problem&lt;/a&gt; and again in &lt;a href="https://calyntro.com/blog/posts/2026-06-20-edd-closes-half-the-loop/" rel="noopener noreferrer"&gt;EDD Closes the Loop — But Only Half of It&lt;/a&gt;, we drew a distinction between two kinds of tools that get conflated constantly in AI-assisted development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Awareness tools&lt;/strong&gt; change what someone &lt;em&gt;knows&lt;/em&gt;. A linting warning, an AI review comment, a suggestion to loop in another team — these work only if the person on the receiving end cares to act on them. We called this the receptionist: it notices, it says something, and whether anyone stops depends entirely on whether they were listening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Governance tools&lt;/strong&gt; change what someone &lt;em&gt;can do&lt;/em&gt;. Branch protection, required reviewers, a merge gate that simply will not open. This is the turnstile. It does not negotiate.&lt;/p&gt;

&lt;p&gt;The mistake worth reaching for here is a receptionist when the situation actually calls for a turnstile — an AI review that correctly flagged a risky interface change, and a developer who merged anyway, because a correct recommendation with no teeth is still just a recommendation.&lt;/p&gt;

&lt;p&gt;Writing a single onboarding document for forty developers repeats the same pattern, mirrored. A planning requirement is, by nature, a receptionist: it asks a developer to pause and think before acting. That is exactly the right amount of friction for someone two weeks into agentic coding. For a developer who has been doing this — internalized, automatic, several skills deep — the same instruction is a receptionist stopping someone who already has full clearance, every single time, for no reason connected to actual risk.&lt;/p&gt;

&lt;p&gt;Conversely, treating onboarding guardrails as if they were optional — something a confident developer can simply choose to skip — quietly turns governance into awareness for everyone, the moment the most senior person in the room decides the rule doesn't apply to them today.&lt;/p&gt;

&lt;p&gt;One document was being asked to do two jobs it cannot do at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Layers, Not One Document
&lt;/h2&gt;

&lt;p&gt;Once you see it this way, the fix follows the same shape we landed on for the merge gate: keep awareness and governance as genuinely separate layers, not as two paragraphs in the same file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The governance layer stays small, repository-bound, and identical for everyone.&lt;/strong&gt; No direct pushes to protected branches. No changes outside the declared task scope. Mandatory review before merge. This layer is not calibrated to skill — it is calibrated to blast radius, and an agent's blast radius does not shrink because the developer steering it is experienced. It lives in version control, travels with the repository regardless of whose machine it runs on, and is enforced structurally — branch protection, CI gates, CODEOWNERS — not just requested in a prompt. A senior developer cannot read past it any more than a new one can, and that is the point: it was never about trust in the first place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The scaffolding layer is personal, and it is allowed to shrink.&lt;/strong&gt; Explicit planning before a change. A second person in the loop. Verbose reasoning at every step. This is the receptionist, deliberately turned up high for someone still building judgment, and deliberately turned down for someone who has already demonstrated it. It belongs to the individual, not the repository — closer to a personal coding profile than a project rule.&lt;/p&gt;

&lt;p&gt;The honest reframing for the team is this: the planning step was never really a rule about code. It was an externalized form of judgment a developer hadn't built yet — standing in for the second person in our triplet setup. Once that judgment exists, on its own, the scaffolding has done its job and can step back. That is not an exception being granted. It is the scaffolding successfully making itself unnecessary, which was the actual goal the whole time.&lt;/p&gt;

&lt;p&gt;What makes this credible rather than arbitrary is that the path is visible and earnable, not asserted by title or tenure: a developer's track record across actual sessions — no scope violations, sound judgment under review, demonstrated fluency — is what shrinks their scaffolding, not how senior they happen to be on paper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Letting the Data Set the Threshold
&lt;/h2&gt;

&lt;p&gt;There is a version of this that goes one step further, and it connects back to something we have written about from the other direction.&lt;/p&gt;

&lt;p&gt;Skill-level is one axis. It is not the only one that matters. A confident, fast-graduated developer touching a file that has never been part of anything risky is a low-stakes event regardless of who they are. The same developer touching a file that — according to the repository's own history — has repeatedly co-changed with code three other teams depend on is a different situation entirely, independent of their tier.&lt;/p&gt;

&lt;p&gt;This is exactly the signal we described in the last-mile and EDD pieces: change coupling derived from actual commit history, not from someone's static opinion about which files are "important." A newcomer editing an isolated utility function does not need the full weight of scaffolding just because their tier says so. An experienced developer touching a highly coupled interface should not sail through frictionless just because their tier says so either.&lt;/p&gt;

&lt;p&gt;In other words, the threshold for &lt;em&gt;how much&lt;/em&gt; governance or scaffolding applies to a given change can be informed by two inputs at once — who is making the change, and what the change actually touches, according to the codebase's own coupling history — rather than skill-level alone. That keeps the gate honest in both directions: it does not punish a careful newcomer working in a quiet corner of the code, and it does not wave through a confident developer standing at a boundary the repository's history says has never been a purely local decision.&lt;/p&gt;

&lt;p&gt;This integration is not built yet. It is the natural next step once you accept that "who is this developer" and "what does this change actually risk" are two different questions, and that only one of them is about the person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accountability Instead of a Badge
&lt;/h2&gt;

&lt;p&gt;There is a way to sidestep the tiering problem almost entirely — and it starts from a different question. Instead of asking &lt;em&gt;how skilled is this developer&lt;/em&gt;, ask &lt;em&gt;who owns this change&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The answer doesn't change because an agent wrote the diff. "The AI did it" is not a defense for a bug any more than "the linter passed" ever was. The developer opening the pull request owns what's in it, and there is a simple test for whether that ownership is real: can they explain, in review, what the change does and why — without falling back on the agent's own explanation of itself? If they can't, the patch doesn't merge. Not as a verdict on the developer's general competence, but as confirmation that the editor role EDD describes has actually been exercised for this specific change, not merely rubber-stamped.&lt;/p&gt;

&lt;p&gt;This works precisely because it requires no advance categorization of anyone. It is the same rule for the new hire and the ten-year veteran, applied after the fact to the change itself rather than in advance to the person. Combined with approval-required branch protection already in place via CI/CD, it is a turnstile in the proper sense — not a suggestion that explainability would be nice, but a condition the change cannot pass without.&lt;/p&gt;

&lt;p&gt;What this rule doesn't do is tell a developer &lt;em&gt;how&lt;/em&gt; to get to the point of being able to explain a change with confidence when they're not yet sure. That is where scaffolding still earns its place — just offered differently than a tier assigned at onboarding. Rather than the system deciding in advance who needs the planning ritual and who doesn't, the developer decides, per task, whether to invoke it: a "safer mode" — a skill or flag that constrains the agent to the explicitly declared scope and asks before touching anything adjacent — that anyone can reach for, for a single task, without it being a statement about their standing.&lt;/p&gt;

&lt;p&gt;That reframing matters more than it looks. A tier assigned at onboarding is a status. A safer mode invoked for one afternoon because today's change touches unfamiliar territory is a tool. The first labels a person. The second describes a moment — and senior developers reach for it too, on the parts of the codebase they don't know well, which is exactly when they should.&lt;/p&gt;

&lt;p&gt;The design work from the earlier sections doesn't disappear — someone still has to define what "safer mode" actually constrains, and what change-coupling risk should trigger heavier review regardless of who's making the change. What shifts is who decides when to use it, and the explainability gate at the end makes that choice consequential either way: skip the safer mode on an unfamiliar change, and the gap shows up in review, not three weeks later in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thought
&lt;/h2&gt;

&lt;p&gt;The pattern underneath both of these stories — the merge gate and the onboarding document — is the same one: awareness and governance solve different problems, and a tool built for one quietly fails when asked to do the job of the other, often without announcing that it has failed. We caught it once at the point where code meets the repository. It was waiting at the point where a developer meets the agent for the first time, too.&lt;/p&gt;

&lt;p&gt;The fix in both places turns out to be the same shape: keep the governance layer small, universal, and non-negotiable — ownership and explainability, enforced at merge, regardless of who you are — and let the awareness layer be something people choose for themselves, task by task, rather than something assigned to them once and carried as a label.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post extends earlier pieces on the &lt;a href="https://calyntro.com/blog/posts/2026-05-31-last_mile_problem/" rel="noopener noreferrer"&gt;last mile problem in AI-assisted development&lt;/a&gt; and &lt;a href="https://calyntro.com/blog/posts/2026-06-20-edd-closes-half-the-loop/" rel="noopener noreferrer"&gt;why EDD closes only half the loop&lt;/a&gt;, and follows on from &lt;a href="https://calyntro.com/blog/posts/programming_in_threes/" rel="noopener noreferrer"&gt;why we structure development in threes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://calyntro.com/blog/tags/ai-engineering/" rel="noopener noreferrer"&gt;Ai-Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://calyntro.com/blog/tags/developer-tooling/" rel="noopener noreferrer"&gt;Developer Tooling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://calyntro.com/blog/tags/code-governance/" rel="noopener noreferrer"&gt;Code Governance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://calyntro.com/blog/tags/software-architecture/" rel="noopener noreferrer"&gt;Software Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://calyntro.com/blog/tags/team-practices/" rel="noopener noreferrer"&gt;Team Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>What Your Git History Reveals About Team Alignment</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Tue, 23 Jun 2026 16:33:59 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/what-your-git-history-reveals-about-team-alignment-3d9g</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/what-your-git-history-reveals-about-team-alignment-3d9g</guid>
      <description>&lt;h2&gt;
  
  
  What Your Git History Reveals About Team Alignment
&lt;/h2&gt;

&lt;p&gt;Your org chart says one thing. Your Git history says another. They're rarely the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://calyntro.com/blog/posts/2026-06-10-blog_conway_s_law/" rel="noopener noreferrer"&gt;Last week&lt;/a&gt; I wrote about Conway's Law as a measurement problem — the idea that every commit records not just what changed, but how your teams coordinate. That the co-change pattern across thousands of commits is a structural artifact of who talks to whom, day by day, pull request by pull request.&lt;/p&gt;

&lt;p&gt;This week: what it actually looks like when you read that pattern.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Two Answers to "Who Owns This Module?"
&lt;/h3&gt;

&lt;p&gt;Every team has modules they officially own. Usually documented in a wiki, a Notion doc, a team channel description — or, more commonly, in everyone's heads. That's the first answer.&lt;/p&gt;

&lt;p&gt;The Git history has a second answer: who actually commits there, how often, and how recently.&lt;/p&gt;

&lt;p&gt;These two answers diverge more than most engineering leaders expect. Some modules are touched by everyone regardless of who "owns" them. Some are effectively maintained by a single person who moved to a different team two years ago but never handed off their tacit knowledge. Some have cross-team coupling so strong that the team boundary exists in name only — two teams coordinating constantly on a module pair that the architecture diagram shows as independent.&lt;/p&gt;

&lt;p&gt;None of this appears in your architecture diagram. All of it appears in your commit log.&lt;/p&gt;




&lt;h3&gt;
  
  
  Three Patterns That Show Up
&lt;/h3&gt;

&lt;p&gt;When you map team ownership onto co-change history systematically, three patterns emerge with enough consistency to be structurally meaningful:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. De facto ownership drift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modules formally assigned to one team are predominantly committed by contributors assigned elsewhere. The official owner and the practical owner have diverged — not through any explicit decision, but through accumulated pull requests and the organic drift of where work actually lands.&lt;/p&gt;

&lt;p&gt;This is invisible in the org chart. It's unmistakable in the commit history.&lt;/p&gt;

&lt;p&gt;The risk isn't just process messiness. When ownership drifts, so does the knowledge. The person with the deepest understanding of a module may no longer appear on the team's roster. If they leave, that knowledge leaves with them. This is how knowledge silos form — not through negligence, but through momentum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Cross-team coupling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Changes in certain modules are consistently followed by changes in modules assigned to a different team. Not occasionally — consistently. Commit after commit, over weeks or months, one module's changes trigger follow-on work in another team's module.&lt;/p&gt;

&lt;p&gt;This is a coordination dependency that exists in practice but has no formal representation. It doesn't show up in the dependency graph. It doesn't appear in the sprint board. It surfaces only as recurring synchronization meetings, Slack threads that say "did you already update X for this?", and the ambient friction that slows down work without ever having a clear name.&lt;/p&gt;

&lt;p&gt;The co-change pattern makes it visible and measurable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Asymmetric dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the strongest coupling pairs, the dependency runs in one direction. Module A consistently drives changes in Module B — but changes in B rarely require changes in A.&lt;/p&gt;

&lt;p&gt;Symmetric coupling can be coincidental: two modules that happen to appear in the same large refactors. Asymmetric coupling is a structural signal. When A always drives B but not the reverse, there is an implicit architectural dependency that was never formally designed — it just accumulated. And whoever maintains A has to think about B every time, whether they're supposed to or not.&lt;/p&gt;

&lt;p&gt;At scale, asymmetric cross-team coupling is one of the clearest indicators that a formal API boundary needs to be drawn. Not as a bureaucratic constraint, but because the coupling already exists and making it explicit would reduce the coordination cost rather than add to it.&lt;/p&gt;




&lt;h3&gt;
  
  
  The MongoDB Experiment
&lt;/h3&gt;

&lt;p&gt;To illustrate what this analysis actually surfaces, we ran it on the MongoDB open-source repository with a simulated team structure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important disclaimer:&lt;/strong&gt; MongoDB is an open-source project with no official team structure. The team assignments used in this analysis are constructed for demonstration purposes — not derived from any real organizational data. The Git history and co-change patterns are real. The team boundaries are not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was a deliberate choice: a codebase large enough to produce statistically meaningful patterns, without misrepresenting any real organization.&lt;/p&gt;

&lt;p&gt;What emerged:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;492 coupled module pairs&lt;/strong&gt; detected across the repository&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;167 of those (34%) crossed simulated team boundaries&lt;/strong&gt; — Conway's Law violations relative to the structure we assigned&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;46,208 coordination events&lt;/strong&gt; where a cross-team change was followed by a follow-on change in another team's module&lt;/li&gt;
&lt;li&gt;Clear directional asymmetry in a subset of pairs: one module consistently drove the other, not the reverse&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The patterns were structurally coherent. The modules with strong directional cross-team coupling were the ones where, in a real organization, you'd expect engineering leads to be having the same conversation repeatedly: "why does every change in X require a change in Y?"&lt;/p&gt;

&lt;p&gt;That conversation is expensive. It usually happens informally, without any record. It doesn't appear in retrospectives or architecture reviews. But it appears in the commit history — if you look.&lt;/p&gt;

&lt;p&gt;You can explore the full MongoDB analysis at &lt;a href="https://demo.calyntro.com" rel="noopener noreferrer"&gt;demo.calyntro.com&lt;/a&gt; — no login required.&lt;/p&gt;




&lt;h3&gt;
  
  
  Three Questions This Makes Answerable
&lt;/h3&gt;

&lt;p&gt;For an engineering leader, the practical value of this analysis isn't the metrics themselves — it's the questions they make answerable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which modules are creating hidden coordination overhead between teams?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not the dependencies that are formally documented and managed, but the ones that emerge organically from how the work actually gets done. The ones where a change in team A's module silently requires someone from team B to follow up — with no mechanism to make that dependency visible until it's already causing friction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does your architecture reflect how your teams actually work — or how they're supposed to work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Org charts and architecture diagrams describe intention. Commit history describes reality. The gap between them is where Conway's Law lives, and where the invisible coordination costs accumulate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a planned reorganization going to reduce coupling or increase it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before restructuring teams, you can look at the current coupling patterns and reason about which new structure aligns with actual co-change behavior — and which modules would need to be actively refactored to make a new structure viable without increasing coordination overhead.&lt;/p&gt;

&lt;p&gt;These questions aren't new. What's new is that they're answerable from existing data — without instrumentation, without surveys, without source code access. The signal has been accumulating in your repository since the first commit.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why This Is Different from Static Dependency Analysis
&lt;/h3&gt;

&lt;p&gt;Static dependency analysis tells you what the code imports. That's useful, but it captures only formal, explicit dependencies.&lt;/p&gt;

&lt;p&gt;Git history tells you what the code needs to change together in practice. That includes implicit dependencies — shared data contracts, configuration coupling, behavioral assumptions that are tested together even when they're not linked in the import graph. It includes the operational dependencies that emerge from how the system is actually deployed and maintained.&lt;/p&gt;

&lt;p&gt;And it includes something no static analysis tool can capture: the organizational signal. A co-change pattern between two modules doesn't just tell you about the code — it tells you about the &lt;em&gt;people&lt;/em&gt;. About who coordinates with whom, how often, and in which direction.&lt;/p&gt;

&lt;p&gt;That's the Conway's Law signal. And reading it doesn't require any changes to your development process.&lt;/p&gt;




&lt;h3&gt;
  
  
  What This Looks Like in Practice
&lt;/h3&gt;

&lt;p&gt;The Team Alignment view in Calyntro makes this analysis operational. You define your team structure — which contributors belong to which team, which modules fall under which team's ownership — and the analysis maps your actual co-change history against that structure.&lt;/p&gt;

&lt;p&gt;The output answers the questions above directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modules with cross-team co-change patterns, ranked by coupling strength&lt;/li&gt;
&lt;li&gt;Directionality scores for each pair — which module is the driver&lt;/li&gt;
&lt;li&gt;Ownership drift: modules where the de facto contribution pattern doesn't match the assigned owner&lt;/li&gt;
&lt;li&gt;Knowledge concentration: where a single contributor (regardless of team) has accumulated the bulk of recent commits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The analysis runs on your Git history. No source code is parsed. No external data is required. Nothing leaves your infrastructure.&lt;/p&gt;

</description>
      <category>conwayslaw</category>
      <category>gitanalysis</category>
      <category>architecture</category>
      <category>teamtopologies</category>
    </item>
    <item>
      <title>EDD Closes the Loop — But Only Half of It</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Sat, 20 Jun 2026 13:22:43 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/edd-closes-the-loop-but-only-half-of-it-3984</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/edd-closes-the-loop-but-only-half-of-it-3984</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkfradt77wp8j1synd3wk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkfradt77wp8j1synd3wk.png" alt=" " width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A recent piece by &lt;a href="https://www.linkedin.com/in/andrealaforgia/" rel="noopener noreferrer"&gt;Andrea Laforgia&lt;/a&gt; on Expectation-Driven Development (EDD) made the rounds, and it deserves serious attention. The core argument is compelling: AI agents produce code faster than humans can meaningfully review it, so we need a structured protocol for specifying intent before implementation and demanding evidence of fulfillment afterward. The human developer transitions from &lt;em&gt;author&lt;/em&gt; to &lt;em&gt;editor&lt;/em&gt; — from writing code to evaluating it.&lt;/p&gt;

&lt;p&gt;That framing is right. And the EDD workflow — write expectations in plain text, let the agent implement, ask the agent to prove it, challenge the evidence, iterate — is a real improvement over the current default, which is roughly "trust and hope the CI is green."&lt;/p&gt;

&lt;p&gt;But EDD solves a specific problem: the gap between &lt;em&gt;human intention&lt;/em&gt; and &lt;em&gt;AI implementation&lt;/em&gt;. It does not solve the problem that comes next.&lt;/p&gt;

&lt;p&gt;To make this concrete, picture a developer asking an agent to fix how discount codes are applied at checkout. The expectation is precise: discounts apply to the pre-tax subtotal, tax is calculated after, an empty cart returns zero rather than an error. The agent implements it, runs the test suite, and produces evidence — three scenarios with real numbers, matching exactly what was specified. The developer reviews the evidence adversarially, pushes back once on a stacked-discount edge case, gets a revised version, and is satisfied. This is EDD working exactly as intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where EDD Stops
&lt;/h2&gt;

&lt;p&gt;EDD ends when the developer is satisfied with the evidence. The expectation has been met. The code works. The diff is ready.&lt;/p&gt;

&lt;p&gt;What happens after that?&lt;/p&gt;

&lt;p&gt;In most teams, the answer is: it gets merged. Maybe a colleague glances at the diff. Maybe not. The CI is green, the expectations were verified (at least in the agent's own estimation), and the code lands in the main branch.&lt;/p&gt;

&lt;p&gt;In our example, the discount fix touched a shared &lt;code&gt;PricingEngine&lt;/code&gt; interface — the same one the inventory team's reservation logic depends on. Nobody chose to ignore that. It simply wasn't part of the expectation. The expectation was about discounts and tax, not about who else reads from that interface. Three weeks later, a reservation bug surfaces that takes two days to trace back to this merge.&lt;/p&gt;

&lt;p&gt;This is precisely where a different problem begins — the distance between &lt;em&gt;finished code&lt;/em&gt; and &lt;em&gt;trusted repository&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;EDD is, at its core, an awareness tool. It makes the developer better informed about whether the code fulfills its stated intent. But awareness tools have a structural limitation: their effectiveness depends entirely on whether someone acts on what they now know. A very thorough EDD process can still produce a merge that silently violates an architectural boundary — not because the code is wrong, but because the expectations never captured the right constraints.&lt;/p&gt;

&lt;p&gt;Nobody wrote an expectation that said: &lt;em&gt;"This change must not modify a shared interface that three other teams depend on without their knowledge."&lt;/em&gt; That kind of constraint does not live in the feature spec. It lives in the structure of the codebase.&lt;/p&gt;

&lt;p&gt;Think of the difference as a receptionist versus a turnstile. A receptionist notices if someone heading into a restricted area looks like they don't belong, and says something. Whether that visitor stops depends entirely on whether they care to listen. A turnstile does not notice anything — it simply does not open without the right badge. EDD, however thorough, is a receptionist. It can flag, advise, and warn. It cannot stop a determined merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Different Problems, Two Different Tools
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Specification problems&lt;/strong&gt; ask: &lt;em&gt;Does the code do what I intended?&lt;/em&gt; EDD addresses this. It forces developers to articulate intent before implementation and to demand evidence that the intent was fulfilled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coordination problems&lt;/strong&gt; ask: &lt;em&gt;Does this change affect something that belongs to someone else?&lt;/em&gt; No amount of expectation-writing resolves this, because the affected parties are not in the room. The constraint is not derivable from the feature spec alone. It requires knowledge of the codebase's actual coupling structure — which files have historically changed together, which teams own which components, where the real boundaries are.&lt;/p&gt;

&lt;p&gt;EDD is designed for the first problem. It is not designed for the second. Applying it to the second produces a feeling of rigor without the substance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Repository Already Knows
&lt;/h2&gt;

&lt;p&gt;The good news is that coordination problems leave traces.&lt;/p&gt;

&lt;p&gt;When two components are genuinely coupled — when changing one reliably requires changing the other — that pattern shows up in the commit history. Files that have been modified together repeatedly across time exhibit &lt;em&gt;change coupling&lt;/em&gt;: a data signal derived not from someone's opinion about the architecture, but from the actual history of how the codebase evolved.&lt;/p&gt;

&lt;p&gt;A seismograph does not predict an earthquake by reasoning about plate tectonics from first principles. It records vibration, and the pattern of past vibration tells you something real about where the next one is likely to originate. Change coupling works the same way: it does not need to understand &lt;em&gt;why&lt;/em&gt; &lt;code&gt;PricingEngine&lt;/code&gt; and the inventory reservation logic are related. It only needs to notice that, across forty prior commits, they have moved together twenty-three times. That is enough to raise a flag worth taking seriously.&lt;/p&gt;

&lt;p&gt;That distinction — between an advisory generated from a prompt and a trigger generated from data — is the difference between awareness and governance. One is an opinion about what might matter. The other is evidence about what has mattered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Halves of the Loop
&lt;/h2&gt;

&lt;p&gt;The full workflow for AI-assisted development looks like a loop with two distinct halves:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First half (EDD):&lt;/strong&gt; Specify intent → agent implements → agent proves → human challenges → iterate to convergence. This closes the gap between what the developer wanted and what the agent produced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second half (Change Coupling + Governance):&lt;/strong&gt; Before merge, check whether the change crosses an ownership boundary that the repository's history suggests is real. If it does, trigger a coordination step — not as a suggestion, but as a requirement.&lt;/p&gt;

&lt;p&gt;Neither half replaces the other. EDD without governance produces well-specified code that still merges silently across team boundaries. Governance without EDD produces gates that catch coordination problems but does nothing about specification problems. Together, they address the full distance from intent to repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Deeper Point
&lt;/h2&gt;

&lt;p&gt;Laforgia is honest about one of EDD's core weaknesses: the fox-guarding-the-henhouse problem. The same AI that wrote the code produces the evidence that the code works.&lt;/p&gt;

&lt;p&gt;But the governance half of the loop has its own version of this problem. If the gate is based on static rules — &lt;em&gt;interface changes always require review&lt;/em&gt; — then developers learn to route around it. The rules are too blunt. The gate becomes theater.&lt;/p&gt;

&lt;p&gt;The alternative is a gate grounded in something the codebase itself produced: coupling patterns derived from the actual commit history, mapped to the actual ownership structure. When the repository's own history says that changes in this area have not historically been local decisions, that is not an opinion. That is data.&lt;/p&gt;

&lt;p&gt;The last mile is not a place for better prompts. It is a place for better data — and for making sure that data has teeth.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://calyntro.com/blog/2026-06-20-edd-closes-half-the-loop" rel="noopener noreferrer"&gt;calyntro.com&lt;/a&gt;. Calyntro surfaces change coupling patterns from Git history and maps them to team ownership — turning the repository's own history into a governance signal. &lt;a href="https://demo.calyntro.com" rel="noopener noreferrer"&gt;Explore the live demo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Beyond Bus Factor: Detecting Combined Knowledge and Coupling Risk From Git History</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Tue, 16 Jun 2026 12:55:21 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/beyond-bus-factor-detecting-combined-knowledge-and-coupling-risk-from-git-history-3ka6</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/beyond-bus-factor-detecting-combined-knowledge-and-coupling-risk-from-git-history-3ka6</guid>
      <description>&lt;h2&gt;
  
  
  How ownership analysis changes when you layer in change coupling — with real findings from the MongoDB open-source repo.
&lt;/h2&gt;

&lt;p&gt;Most tools that measure bus factor stop at the number. One person owns this module. Here is the percentage. Good luck.&lt;/p&gt;

&lt;p&gt;That's useful context. It's not useful guidance.&lt;/p&gt;

&lt;p&gt;The question an engineering leader actually needs answered isn't &lt;em&gt;how concentrated is the knowledge?&lt;/em&gt; — it's &lt;em&gt;what do I do about it, and where do I start?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Raw Risk Metrics
&lt;/h2&gt;

&lt;p&gt;Knowledge concentration exists in virtually every codebase. Run any ownership analysis on a real production repository and you'll find modules where one person did 80% of the meaningful work. You'll find files nobody else has touched in two years. You'll find developers who accumulated knowledge across hundreds of commits that isn't written down anywhere.&lt;/p&gt;

&lt;p&gt;Showing all of that at once produces a list of concerns. It doesn't produce a priority.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changes When You Add Context
&lt;/h2&gt;

&lt;p&gt;We ran Knowledge Risk analysis on the MongoDB open-source repository (~500k commits). The analysis surfaces five recommended actions, ranked by severity. Three are marked &lt;strong&gt;critical&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's the most urgent finding, in the exact language the analysis produces:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Single point of failure — Developer 1389 is the sole owner of 116 files in src_third_party, with 1,551 commits of accumulated activity."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Recommended action: &lt;em&gt;"Initiate knowledge transfer — no secondary owner in high-churn module."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's not a metric. That's a sentence you can read in a planning meeting and act on the same week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Combined Risk Signal
&lt;/h2&gt;

&lt;p&gt;The more interesting finding is what happens when you look at two analytical dimensions together.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bazel_resmoke&lt;/code&gt; is a small module — 3 files, 100% silo ratio. One developer, no secondary owner. Flagged as critical.&lt;/p&gt;

&lt;p&gt;On its own, that's manageable. Small module, isolated risk, schedule a knowledge transfer session.&lt;/p&gt;

&lt;p&gt;Now add: &lt;code&gt;bazel_resmoke&lt;/code&gt; changes together with &lt;code&gt;src_mongo&lt;/code&gt; at a coupling score of 100 — cross-team.&lt;/p&gt;

&lt;p&gt;The analysis flags this as: &lt;strong&gt;"Combined risk: ownership concentration + cross-team coupling."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recommended action: &lt;em&gt;"Priority: bazel_resmoke couples strongly with src_mongo — silo risk is amplified by cross-team coupling."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This changes the response entirely. It's not just "schedule a knowledge transfer session." It's "this module's isolation doesn't just affect one team — it affects the team that depends on it too." Two teams need to be part of the conversation.&lt;/p&gt;

&lt;p&gt;A silo risk and a coupling risk, separately, are each manageable. Together, they amplify. If the sole owner leaves, the coupled cross-team dependency loses its primary contact point on both sides simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prioritisation by Severity
&lt;/h2&gt;

&lt;p&gt;The Knowledge Risk view produces a sorted list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical&lt;/strong&gt; — sole ownership + high activity + no secondary coverage → act now&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch&lt;/strong&gt; — ownership concentration increasing month-over-month → monitor, plan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elevated&lt;/strong&gt; — measurable risk, not yet acute → track&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That ordering matters. 17 of 43 MongoDB modules show measurable knowledge risk. If everything is equally urgent, nothing gets addressed. The severity ranking turns a list of concerns into a sequence of decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Analysis Works
&lt;/h2&gt;

&lt;p&gt;This runs entirely from Git history. No source code access. No interviews. No dependency on team members self-reporting their expertise.&lt;/p&gt;

&lt;p&gt;The Git history records who built what, when, and how much. &lt;strong&gt;Temporal ownership&lt;/strong&gt; — who owned the code &lt;em&gt;when the meaningful decisions were made&lt;/em&gt;, not just who last touched it — is what makes the signal credible.&lt;/p&gt;

&lt;p&gt;A module that was built entirely by someone who left 18 months ago doesn't look risky in a current ownership snapshot. It looks risky in the historical record.&lt;/p&gt;




&lt;p&gt;The full MongoDB analysis is live at &lt;a href="https://demo.calyntro.com" rel="noopener noreferrer"&gt;demo.calyntro.com&lt;/a&gt; — no login required. To run this on your own repository: &lt;a href="https://calyntro.com/#contact" rel="noopener noreferrer"&gt;calyntro.com/#contact&lt;/a&gt;. Self-hosted. Nothing leaves your infrastructure.&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>git</category>
      <category>leadership</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Bad Sprints Start Before the Sprint</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Mon, 15 Jun 2026 07:08:28 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/bad-sprints-start-before-the-sprint-2okk</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/bad-sprints-start-before-the-sprint-2okk</guid>
      <description>&lt;p&gt;There's a recurring debate in agile circles about why teams miss deadlines. The usual suspects: bad estimates, too many columns in Jira, missing WIP limits, the wrong metrics.&lt;/p&gt;

&lt;p&gt;The fixes that follow are predictable. Reconfigure the board. Add a Cycle Time chart. Apply Little's Law. Run a retrospective about why the sprint went sideways — again.&lt;/p&gt;

&lt;p&gt;These interventions aren't wrong. But they're downstream of the actual problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Board Shows What Refinement Produced
&lt;/h2&gt;

&lt;p&gt;A Scrum board is a mirror. It reflects the quality of the decisions made before the sprint started. If those decisions were vague, the board will look chaotic — not because of how the columns are arranged, but because the work itself was never properly understood.&lt;/p&gt;

&lt;p&gt;Here's what that looks like in practice:&lt;/p&gt;

&lt;p&gt;A ticket sits in "In Progress" for three weeks. Was it blocked? Was it actively worked on? Was the scope unclear from day one? The board can't tell you. It only records that someone started it and nobody finished it.&lt;/p&gt;

&lt;p&gt;Meanwhile, in the last refinement session, the team estimated the ticket in two hours and moved on.&lt;/p&gt;

&lt;p&gt;The board didn't fail. The refinement did.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens When Refinement Is Skipped or Rushed
&lt;/h2&gt;

&lt;p&gt;Poor refinement produces three predictable failure patterns:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Work that can't be started cleanly.&lt;/strong&gt; The developer picks up a ticket, reads it, and immediately has three questions that weren't answered in refinement. She spends half a day tracking down the product owner, waits for answers, loops back. That's not a board problem. That's a definition problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Work that can't be estimated reliably.&lt;/strong&gt; Packages that are too large hide complexity. A ticket labeled "Implement payment flow" could mean two days or two weeks, depending on what's inside. No estimation technique — story points, hours, T-shirt sizes — saves you from that ambiguity. You have to break it apart first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Work that collides with other work mid-sprint.&lt;/strong&gt; When dependencies between tickets aren't surfaced in refinement, they emerge during implementation. Suddenly two developers are blocked on each other, or a backend change breaks a frontend assumption nobody knew existed.&lt;/p&gt;

&lt;p&gt;All three failure patterns end up looking the same on the board: things that were supposed to be done aren't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refinement Is Risk Management
&lt;/h2&gt;

&lt;p&gt;The most useful reframe: refinement is not about estimation. It's about de-risking.&lt;/p&gt;

&lt;p&gt;When you refine a ticket thoroughly — defining acceptance criteria, breaking it into manageable pieces, surfacing dependencies, aligning on what "done" actually means — you're not trying to predict the future more accurately. You're shrinking the surface area of surprises.&lt;/p&gt;

&lt;p&gt;This matters enormously for delivery predictability. A team working with well-refined tickets will have much more stable Cycle Times than a team working with vague ones. Not because they're faster, but because their work is more consistent. Outliers — the tickets that drag on for weeks — almost always trace back to unclear scope at the start.&lt;/p&gt;

&lt;p&gt;Little's Law requires process stability to produce meaningful forecasts. Refinement is what creates that stability, long before the sprint starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Good Refinement Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;Not a checklist. A conversation with a specific goal: at the end of this session, can everyone on the team independently describe what needs to be built, how we'll know it's done, and what could slow us down?&lt;/p&gt;

&lt;p&gt;Some practical markers:&lt;/p&gt;

&lt;p&gt;Tickets are small enough that no one person can "own" them for two weeks unnoticed. If a ticket takes longer than two or three days, it's probably too large.&lt;/p&gt;

&lt;p&gt;Acceptance criteria are written in terms of observable behavior, not implementation steps. "User can complete checkout without re-entering payment details" is testable. "Implement payment caching" is not.&lt;/p&gt;

&lt;p&gt;Dependencies on other teams, services, or people are named explicitly — not assumed. If the ticket requires input from the data team, that's in the ticket. If it touches a shared service, that's in the ticket.&lt;/p&gt;

&lt;p&gt;Edge cases are acknowledged. Not necessarily solved, but known. "We don't yet know how this behaves with expired sessions" is useful information. Pretending the question doesn't exist is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Board Becomes Useful Once Refinement Works
&lt;/h2&gt;

&lt;p&gt;When refinement is treated as the foundation rather than a formality, something changes in how the board behaves.&lt;/p&gt;

&lt;p&gt;WIP naturally stays lower, because teams aren't juggling partially-understood tickets that stall and pile up. Cycle Times stabilize, because the work is more homogeneous. The daily standup becomes less about status and more about obstacles — because the main question shifts from "what am I still figuring out?" to "what's blocking me from finishing what I understand?"&lt;/p&gt;

&lt;p&gt;At this point, board metrics start to mean something. Cycle Time distributions tighten. Throughput becomes a reliable signal. Forecasting becomes a tool rather than a performance.&lt;/p&gt;




&lt;p&gt;Work that was poorly understood at the start leaves a recognizable trail in the repository — in how it gets revised, extended, and fixed after the fact. Many of those patterns have a refinement signature: unexpected coupling, knowledge concentrated in one person, hotspots that absorb disproportionate change. The board doesn't show this. The Git history does.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://calyntro.com" rel="noopener noreferrer"&gt;Calyntro&lt;/a&gt;, we analyze that history to surface exactly these signals — before they become the next sprint's problem.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>scrum</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Conway's Law Is Already in Your Commit History</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Wed, 10 Jun 2026 20:30:08 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/conways-law-is-already-in-your-commit-history-38a5</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/conways-law-is-already-in-your-commit-history-38a5</guid>
      <description>&lt;p&gt;Conway's Law was formulated in 1967. It says: any organization that designs a system will produce a design whose structure mirrors the organization's communication structure.&lt;/p&gt;

&lt;p&gt;Fifty-eight years later, most engineering teams treat it as a useful metaphor. Something to quote in architecture reviews and then move on.&lt;/p&gt;

&lt;p&gt;I've started treating it as a measurement problem.&lt;/p&gt;

&lt;p&gt;The question isn't whether Conway's Law applies to your organization — it does, almost certainly. The question is whether you can see &lt;em&gt;how&lt;/em&gt; it applies. And until recently, that required expensive org mapping exercises, workshops, and a lot of guesswork.&lt;/p&gt;

&lt;p&gt;Your Git history already contains the answer.&lt;/p&gt;

&lt;p&gt;Every commit records what changed, when, and alongside what else. Over thousands of commits, the pattern of what changes together — across which boundaries — is a direct artifact of how your teams coordinate. Not how they're supposed to coordinate. How they actually do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The experiment
&lt;/h2&gt;

&lt;p&gt;To make this concrete, I took the MongoDB open-source repository and assigned a simulated team structure to it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;MongoDB has no official teams&lt;/strong&gt; — it's an open-source project. This was a deliberate experiment to test whether Conway's Law shows up in Git metadata. The commit history is real. The team assignments are not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What showed up was clear: coupling patterns that crossed team boundaries were visible directly in the commit log. Modules assigned to different teams changed together, consistently, over time. Not because someone designed it that way. Because the people doing the work were coordinating — and coordination leaves traces.&lt;/p&gt;

&lt;p&gt;The asymmetry was particularly striking. Some dependencies were one-directional: module A consistently triggered changes in module B, but not the other way around. That's not coincidence. That's an architectural signal — a hidden dependency that no diagram captures, but that every engineer on the team implicitly knows about.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgejm7tfctr5k48mfyhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgejm7tfctr5k48mfyhr.png" alt=" " width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means in a real organization
&lt;/h2&gt;

&lt;p&gt;In an open-source project, there are no formal teams — so the simulation is just that. But in an organization with real team structures, this analysis becomes a diagnostic tool.&lt;/p&gt;

&lt;p&gt;Which modules are your teams creating invisible dependencies between? Where are coordination costs accumulating without anyone naming them? Does your architecture actually reflect how your teams work — or how you think they work?&lt;/p&gt;

&lt;p&gt;These are questions your Git history can answer. The data has always been there. What was missing was a way to read it.&lt;/p&gt;

&lt;p&gt;That's what we're building with &lt;a href="https://calyntro.com" rel="noopener noreferrer"&gt;Calyntro&lt;/a&gt; — a self-hosted repository intelligence tool that analyzes Git history to surface knowledge silos, coupling patterns, and Conway's Law violations. Nothing leaves your infrastructure.&lt;/p&gt;

&lt;p&gt;The MongoDB analysis is live at &lt;a href="https://demo.calyntro.com" rel="noopener noreferrer"&gt;demo.calyntro.com&lt;/a&gt; — no login required.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://calyntro.com/blog/2026-06-10-conways-law-git-history" rel="noopener noreferrer"&gt;Calyntro blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>architecture</category>
      <category>teamtopology</category>
      <category>devops</category>
    </item>
    <item>
      <title>Software Engineering: The Art of Thinking Out Loud (with AI)</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Thu, 28 May 2026 12:38:47 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/software-engineering-the-art-of-thinking-out-loud-with-ai-4lnn</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/software-engineering-the-art-of-thinking-out-loud-with-ai-4lnn</guid>
      <description>&lt;p&gt;A colleague said something to me recently that I keep coming back to:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Often, by the time you've finished articulating a complex problem for the AI, you've already solved it yourself."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It sounds almost like a joke. You open a chat window, start typing out your problem in careful detail — and somewhere in the middle of the second paragraph, the answer appears. Not from the AI. From you.&lt;/p&gt;

&lt;p&gt;If you've worked with LLMs seriously, you've probably experienced this. And I think it points to something important about what is actually changing in our craft — something that goes beyond the usual conversation about automation and job displacement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rubber Duck, Promoted
&lt;/h2&gt;

&lt;p&gt;Developers have known for decades that explaining a problem out loud helps solve it. The classic technique involves a rubber duck: you place it on your desk, narrate your code to it, and the act of articulation forces you to confront the assumptions you'd quietly made. The duck never responds. That's not the point.&lt;/p&gt;

&lt;p&gt;The LLM is a rubber duck that occasionally says something useful back.&lt;/p&gt;

&lt;p&gt;But even when it doesn't — even when the response is generic or slightly off — the discipline of formulating the prompt has already done its work. You've had to be precise. You've had to strip away ambiguity. You've had to decide what actually matters.&lt;/p&gt;

&lt;p&gt;That process is not a workaround. It is thinking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Inversion of the Workflow
&lt;/h2&gt;

&lt;p&gt;In the pre-AI era, the typical development workflow looked something like this: you had a rough mental model of the solution, you started coding, and you discovered the edge cases along the way. The code was exploratory. The thinking happened during the writing.&lt;/p&gt;

&lt;p&gt;With AI assistance, that workflow inverts. Vague inputs produce vague outputs — the model has no way to compensate for an underspecified problem. So precision becomes mandatory upfront. You have to think before you type, not while you type.&lt;/p&gt;

&lt;p&gt;This is a more demanding cognitive posture. It requires holding the full shape of a problem in your head before committing to an approach. For experienced developers, this often feels natural — it's close to what they were already doing mentally. For less experienced developers, it can feel like a new kind of friction.&lt;/p&gt;

&lt;p&gt;That friction is not a bug. It's the learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation Over Construction
&lt;/h2&gt;

&lt;p&gt;There's a second shift worth naming: the center of gravity in engineering work is moving from construction to validation.&lt;/p&gt;

&lt;p&gt;When I can generate a working implementation in minutes, the scarce resource is no longer the implementation — it's the judgment to know whether the implementation is &lt;em&gt;right&lt;/em&gt;. Right for the requirements. Right for the system it lives in. Right for the team that will maintain it in eighteen months.&lt;/p&gt;

&lt;p&gt;This kind of validation requires something the AI doesn't have: context. Not just the context of this ticket, or this sprint, but the accumulated context of this codebase, this team, this organization's history of decisions. The AI can tell you whether the code compiles and whether it handles the happy path. It cannot tell you whether this is the kind of abstraction your team will still understand in two years.&lt;/p&gt;

&lt;p&gt;That judgment — the ability to look at something technically correct and say &lt;em&gt;"this is wrong for us"&lt;/em&gt; — is increasingly the most valuable thing a senior engineer brings to the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cognitive Offloading Trap
&lt;/h2&gt;

&lt;p&gt;Here's the risk I want to name directly: if we use AI purely as a cognitive offloading tool — a way to avoid thinking rather than a mirror to think against — we gradually erode the very capability that makes us useful.&lt;/p&gt;

&lt;p&gt;It's subtle. Each individual decision to let the AI handle something feels reasonable. The cumulative effect is that we stop exercising the muscles that generate real insight. We become reviewers of outputs we no longer fully understand. We lose the thread.&lt;/p&gt;

&lt;p&gt;The antidote isn't to use AI less. It's to use it differently — as an interlocutor rather than an oracle. Ask it to challenge your assumptions. Ask it what you might be missing. Ask it to steelman the approach you're &lt;em&gt;not&lt;/em&gt; taking. These prompts don't just produce better outputs; they produce better thinking.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Next Generation Will Actually Need
&lt;/h2&gt;

&lt;p&gt;The skills that defined excellent engineers ten years ago — typing speed, syntax recall, pattern library depth — are depreciating. The skills that are appreciating are older and harder to teach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structured thinking.&lt;/strong&gt; The ability to decompose a complex problem into parts that are independently understandable and collectively complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precise communication.&lt;/strong&gt; Not just writing clear code, but articulating requirements, constraints, and assumptions in ways that leave no ambiguity — for the AI, yes, but more importantly for your team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Critical evaluation.&lt;/strong&gt; The habit of asking &lt;em&gt;why does this work?&lt;/em&gt; rather than accepting that it does. Of stress-testing a solution against its own assumptions before shipping it.&lt;/p&gt;

&lt;p&gt;None of these are new. What's new is that they are now the primary differentiator. The floor has risen for everyone. The ceiling belongs to the people who can think clearly about hard problems — and who have built the discipline to do so even when a faster, easier path is one prompt away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have You Already Solved It?
&lt;/h2&gt;

&lt;p&gt;Next time you sit down to write a prompt for a difficult problem, pay attention to what happens as you write. Notice when the act of articulation clarifies something you didn't know you were confused about. Notice when the constraint of explaining your reasoning exposes a gap in it.&lt;/p&gt;

&lt;p&gt;The AI may or may not give you a useful answer. But you will have thought more clearly than you would have otherwise. And in the long run, that compound interest in thinking quality is worth more than any individual answer the model produces.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post is part of an ongoing series exploring the intersection of engineering practice and the changing landscape of AI tooling.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>discuss</category>
      <category>career</category>
    </item>
    <item>
      <title>Why 'Who Last Touched This File' Is the Wrong Question</title>
      <dc:creator>karl-heinz reichel</dc:creator>
      <pubDate>Wed, 27 May 2026 19:20:47 +0000</pubDate>
      <link>https://dev.to/karlheinz_reichel_7ee08d/why-who-last-touched-this-file-is-the-wrong-question-54ii</link>
      <guid>https://dev.to/karlheinz_reichel_7ee08d/why-who-last-touched-this-file-is-the-wrong-question-54ii</guid>
      <description>&lt;p&gt;A file can have five contributors on record and still be fully owned by&lt;br&gt;
someone who left the company fourteen months ago.&lt;/p&gt;

&lt;p&gt;The commit history looks healthy. The risk is invisible.&lt;/p&gt;

&lt;p&gt;This is the gap that most repository analytics tools don't close — and&lt;br&gt;
the reason I built Calyntro around a different concept: &lt;strong&gt;temporal ownership&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem with Static Ownership Snapshots
&lt;/h2&gt;

&lt;p&gt;Standard ownership tools take a snapshot. They look at the current state&lt;br&gt;
of the repository and assign files to whoever touched them most recently,&lt;br&gt;
or most often, within a fixed window.&lt;/p&gt;

&lt;p&gt;That snapshot misses something critical: &lt;strong&gt;time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consider a module where one developer wrote 80% of the code over a&lt;br&gt;
two-year period, then left 18 months ago. Since their departure, three&lt;br&gt;
other developers have each made small fixes. A static tool shows:&lt;br&gt;
four contributors, recent activity, looks fine.&lt;/p&gt;

&lt;p&gt;What it doesn't show: the architectural decisions, the implicit&lt;br&gt;
constraints, the edge cases that were never documented — all of that&lt;br&gt;
left with the person who built it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Temporal Ownership: A Different Question
&lt;/h2&gt;

&lt;p&gt;Calyntro tracks what we call &lt;em&gt;temporal ownership&lt;/em&gt; — who wrote the code,&lt;br&gt;
when they wrote it, whether they are still active in that module, and&lt;br&gt;
whether anyone else has built real understanding of it since.&lt;/p&gt;

&lt;p&gt;The question is not "who owns this file today?"&lt;/p&gt;

&lt;p&gt;It is: &lt;strong&gt;"who would be left holding it if the person who built it walked&lt;br&gt;
out the door tomorrow?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This distinction matters most in modules with high churn — code that&lt;br&gt;
is actively changing. A siloed module nobody touches is a known, stable&lt;br&gt;
risk. A siloed module that changes every sprint is an incident waiting&lt;br&gt;
to happen.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Looks Like in Practice: MongoDB
&lt;/h2&gt;

&lt;p&gt;We ran Calyntro against the MongoDB open-source repository — roughly&lt;br&gt;
500,000 commits, one of the most professionally maintained codebases&lt;br&gt;
in the world. Structured contribution guidelines, active code review,&lt;br&gt;
long-term maintainers.&lt;/p&gt;

&lt;p&gt;Here is what temporal ownership analysis found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;17 of 43 modules&lt;/strong&gt; show measurable knowledge risk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2 modules&lt;/strong&gt; at 100% silo ratio — one person, no meaningful backup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 developer&lt;/strong&gt; holds exclusive knowledge of 161 files in a single module&lt;/li&gt;
&lt;li&gt;The module with the &lt;strong&gt;highest churn rate&lt;/strong&gt; carries &lt;strong&gt;38.2% silo risk&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last combination is the most dangerous: code that changes constantly,&lt;br&gt;
understood by exactly one person.&lt;/p&gt;

&lt;p&gt;This is not a startup with three engineers and no processes. If knowledge&lt;br&gt;
concentration shows up in MongoDB, it shows up everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Metrics Calyntro Uses
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Silo Ratio&lt;/strong&gt;&lt;br&gt;
The share of files in a module where a single developer holds exclusive&lt;br&gt;
knowledge. A silo ratio of 100% means one person is the sole knowledge&lt;br&gt;
holder for every file in that module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bus Factor&lt;/strong&gt;&lt;br&gt;
The number of people whose departure would immediately create a knowledge&lt;br&gt;
gap. A bus factor of 1 is a single point of failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Churn Rate&lt;/strong&gt;&lt;br&gt;
How actively a module is changing. High churn combined with high silo&lt;br&gt;
risk is the most dangerous combination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge Risk Score&lt;/strong&gt;&lt;br&gt;
A combined metric that weights silo ratio, churn, and the activity status&lt;br&gt;
of knowledge holders. It surfaces modules that need attention — before&lt;br&gt;
a departure forces the issue.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works Technically
&lt;/h2&gt;

&lt;p&gt;Calyntro reads only Git history — not your source code.&lt;/p&gt;

&lt;p&gt;No code leaves your system. No agents. No instrumentation. The analysis&lt;br&gt;
runs against commit metadata: who committed what, when, to which files,&lt;br&gt;
how often.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend: FastAPI + DuckDB (embedded, no external database required)&lt;/li&gt;
&lt;li&gt;Frontend: React + Vite&lt;/li&gt;
&lt;li&gt;Deployment: Docker, fully self-hosted&lt;/li&gt;
&lt;li&gt;All metrics accessible via open REST API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The DuckDB approach for analytical queries over Git history was one of&lt;br&gt;
the more interesting technical decisions — it handles the time-series&lt;br&gt;
aggregations cleanly without needing a dedicated database server. Happy&lt;br&gt;
to go into detail on that in the comments if there's interest.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Live demo running against the MongoDB repository: &lt;a href="https://demo.calyntro.com" rel="noopener noreferrer"&gt;demo.calyntro.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Self-hosting docs: &lt;a href="https://calyntro.com" rel="noopener noreferrer"&gt;calyntro.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've dealt with knowledge loss after a key engineer left — or you're&lt;br&gt;
trying to figure out which parts of your codebase are quietly becoming&lt;br&gt;
single points of failure — I'd genuinely like to hear how you're&lt;br&gt;
approaching it.&lt;/p&gt;

</description>
      <category>git</category>
      <category>devtools</category>
      <category>softwareengineering</category>
      <category>technicaldept</category>
    </item>
  </channel>
</rss>
