article
This commit is contained in:
parent
88c8c95d0f
commit
c93d7094d4
2 changed files with 187 additions and 0 deletions
|
|
@ -151,6 +151,10 @@
|
|||
<h2 id="writings-header">Writings</h2>
|
||||
<p>Sometimes I like to jot down ideas and drop them here.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="writings/conways-law-cuts-both-ways.html" target="_blank"
|
||||
rel="noopener noreferrer">Conway's Law cuts both ways</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="writings/thoughts-after-departing-galoy.html" target="_blank"
|
||||
rel="noopener noreferrer">Thoughts after departing Galoy</a>
|
||||
|
|
|
|||
183
public/writings/conways-law-cuts-both-ways.html
Normal file
183
public/writings/conways-law-cuts-both-ways.html
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
<!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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue