183 lines
9.7 KiB
HTML
183 lines
9.7 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<title>Pablo here</title>
|
|
<meta charset="utf-8" />
|
|
<meta viewport="width=device-width, initial-scale=1" />
|
|
<link rel="stylesheet" href="../styles.css" />
|
|
</head>
|
|
|
|
<body>
|
|
<main>
|
|
<h1>Hi, Pablo here</h1>
|
|
<p><a href="../index.html">back to home</a></p>
|
|
<hr />
|
|
<section>
|
|
<h2>Conway's Law cuts both ways</h2>
|
|
<p><em>Published: 2026-09-28</em></p>
|
|
|
|
<p>
|
|
This article is a small reflection on a useful way to look at Conway's Law that I think many people working in
|
|
software have not observed. I'll assume you're familiar with Conway's Law. If not, here are some nice explainers
|
|
so you can get on the same page:
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
The original paper: <a href="https://www.melconway.com/research/committees.html" target="_blank"
|
|
rel="noopener noreferrer">How Do Committees invent? by Melvin E. Conway</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://martinfowler.com/bliki/ConwaysLaw.html" target="_blank" rel="noopener noreferrer">Conway's
|
|
Law by Martin Fowler</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
So, to the point: most of the time I bump into someone bringing up Conway's Law, they do so to highlight how the
|
|
organizational and communication structure is impacting the systems that get built. "We should split this team
|
|
into two so one takes service A, the other takes service B and they can work independently". Or, "it's pointless
|
|
that we all try to build on a monolith if the three teams we have are in different time zones, have different
|
|
managers and barely talk with each other". I also find it's used more retrospectively than proactively. That
|
|
is: more as an explanation of how a system came to be the way it is (and usually used when it's fucky), rather
|
|
than a tool to try to influence how a system ends up being. Thoughtworks did introduce the
|
|
<a href="https://www.thoughtworks.com/en-us/insights/blog/customer-experience/inverse-conway-maneuver-product-development-teams"
|
|
target="_blank" rel="noopener noreferrer">Inverse Conway Maneuver</a>, which at least tries to leverage the
|
|
law as a tool of change instead of an a posteriori explainer. Plus: I've never met anyone in real life who was
|
|
familiar with the inverse maneuver.
|
|
</p>
|
|
|
|
<p>
|
|
Where I would like to bring some attention is to the idea of putting it the other way around, in the direction
|
|
of the law: looking at how the code/system changes the org/comms. And to try to use this as a way to influence
|
|
the outcomes of the org, not as a postmortem explanation.
|
|
</p>
|
|
|
|
<p>Let me discuss some examples.</p>
|
|
|
|
<h3>Enforcing boundary contracts</h3>
|
|
|
|
<p>
|
|
In large enough engineering orgs, you end up having Alice's service depend on Bob's public interface. When these
|
|
contracts are purely internal, Bob ends up introducing unexpected breaking changes more often than Alice would
|
|
like, for a variety of reasons. With the consequences being only internal and attributable to reasonable human
|
|
error, I've noticed that serial contract breakers like Bob only get called out if their breakages lead to
|
|
serious outages in a very immediate and direct way.
|
|
</p>
|
|
|
|
<p>
|
|
In one specific instance, I witnessed this setup, which I found interesting: Alice herself added some automated
|
|
CI checks in Bob's repo that enforced what she needed out of his public interface, set up in a way that wouldn't
|
|
allow Bob to go to production while breaking that. Furthermore, she leveraged <code>CODEOWNERS</code> to set the
|
|
repo up so that only her review was valid for these CI checks.
|
|
</p>
|
|
|
|
<p>Bob would have to align with Alice on every breaking change. This resulted in some behaviour changes:</p>
|
|
<ul>
|
|
<li>
|
|
Bob was not deploying breaking changes on his own anymore. Skipping the CI and <code>CODEOWNERS</code> fences
|
|
would have been too daring.
|
|
</li>
|
|
<li>Bob started to think harder about how to execute his work without breaking his contracts with Alice.</li>
|
|
<li>
|
|
Whenever Bob knew he <em>had</em> to break them, he would seek alignment with Alice as early as possible, for
|
|
he knew she was now a bottleneck to his own execution.
|
|
</li>
|
|
<li>
|
|
Bob started to care about having a smaller public surface, and would push Alice hard to include in the
|
|
automated checks only the strict public surface she depended on, and not more.
|
|
</li>
|
|
</ul>
|
|
|
|
<h3>The monolith that wanted to couple</h3>
|
|
|
|
<p>
|
|
In another instance, I worked in a small team that revolved around a single repo. The repo itself held a
|
|
monolith, which was an intentional architectural decision by the group's technical leader. But another
|
|
intentional decision by him was that different modules of that monolith had to stay decoupled from each other:
|
|
he wanted to push harder for a modular monolith, hoping to avoid the dangers of microservices while reaping the
|
|
advantages of a single monolith and of decoupling at the same time.
|
|
</p>
|
|
|
|
<p>
|
|
There were several tricks in his toolbelt to ensure this wasn't broken. One of them was to literally prevent
|
|
imports across modules. Each module could only talk to others through shared infra or explicitly defined public
|
|
APIs. CI checkers would enforce this hard, flagging PRs that tried to skip it.
|
|
</p>
|
|
|
|
<p>A few consequences of this:</p>
|
|
<ul>
|
|
<li>
|
|
The decoupling-by-decree did a decent job at keeping modules decoupled, which gave the engineers working in
|
|
different corners of the monolith good independence to work without being blocked by others. Large reorgs and
|
|
refactors that could be done strictly within the private part of modules mostly happened without other
|
|
colleagues even having to be warned.
|
|
</li>
|
|
<li>
|
|
But living under the same repo umbrella, testing and many other integration tasks were still shared among the
|
|
team, so if you somehow still managed to break someone else's turf, you noticed.
|
|
</li>
|
|
<li>
|
|
The strict no-coupling checks sometimes led to situations where it was extremely tempting to remove the rules
|
|
because it would have made our lives so much easier. Those situations were hints at some shortcoming in the
|
|
wider architecture of the monolith, and led to some very thoughtful whiteboard sessions that helped shape good
|
|
ways to achieve what we wanted without letting the modules talk to each other.
|
|
</li>
|
|
</ul>
|
|
|
|
<h3>The keys to the secrets</h3>
|
|
|
|
<p>
|
|
Another org was struggling with a sprawl of SaaS and infra services being hired left and right. The org had
|
|
grown from a small team to multiple independent teams, and each team was just going around shopping for
|
|
whatever cloud tooling was useful for their work. It quickly grew into a mess of duplicated services, where
|
|
common needs such as observability, documentation or even databases were being served by two or three tools
|
|
where one would have been enough.
|
|
</p>
|
|
|
|
<p>
|
|
The org was lucky enough that at least Git and their pipelines were still centralized in a single place, so the
|
|
following single change was made: one single engineering team, led by a very assertive manager, was put in
|
|
charge of the secrets manager that was used by their CI/CD pipelines. You could only go to production through
|
|
it, and only this manager could actually edit the contents of the vaults to include whatever
|
|
tokens/keys/secrets your tooling needed.
|
|
</p>
|
|
|
|
<p>
|
|
Once this was decided, the first impact was quick: the sprawl stopped because, if you wanted another tool, you
|
|
had to convince that manager, which was anything but trivial. The second effect came in slowly, as certain tools
|
|
were promoted over others and deprecation dates were set under the threat of secrets disappearing from the
|
|
vaults. Initially, this setup was overwhelming for the team sitting on top of the secrets manager, since they
|
|
suddenly became a bottleneck for pretty much every other team in the org. But the pressure incentivized everyone
|
|
to adapt: the gatekeeping team quickly standardized all their business-as-usual to make it as fast and scalable
|
|
as possible. The teams depending on it quickly learned to plan ahead when secrets management was part of some
|
|
line of work, and developed the habit of using what they had available in the org instead of just picking any
|
|
shiny SaaS that was walking by.
|
|
</p>
|
|
|
|
<h3>The take away</h3>
|
|
|
|
<p>
|
|
That's just a few. I could add more, and you would suddenly get bored because the pattern becomes obvious. The
|
|
overarching story to take away: you make some hard rule in code. Because code is stubborn, people adapt around
|
|
it and so your organization and how people work change as a result.
|
|
</p>
|
|
|
|
<p>
|
|
As someone who has both technical and managerial responsibilities, I find this mindset of changing the org via
|
|
the code interesting and useful. I will often find myself thinking: which technical decision will drive the
|
|
behaviour that I want to see in my org?
|
|
</p>
|
|
|
|
<p>
|
|
Is the solution to flip-flopping, mind-changing product owners to make messages containing the words "urgent",
|
|
"change" and "priority" undeliverable in Slack?
|
|
</p>
|
|
|
|
<hr />
|
|
<p><a href="../index.html">back to home</a></p>
|
|
</section>
|
|
</main>
|
|
</body>
|
|
|
|
</html>
|