Hi, Pablo here
+ ++
Conway's Law cuts both ways
+Published: 2026-09-28
+ ++ 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: +
+-
+
- + The original paper: How Do Committees invent? by Melvin E. Conway + +
- + Conway's + Law by Martin Fowler + +
+ 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 + Inverse Conway Maneuver, 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. +
+ ++ 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. +
+ +Let me discuss some examples.
+ +Enforcing boundary contracts
+ ++ 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. +
+ +
+ 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 CODEOWNERS to set the
+ repo up so that only her review was valid for these CI checks.
+
Bob would have to align with Alice on every breaking change. This resulted in some behaviour changes:
+-
+
-
+ Bob was not deploying breaking changes on his own anymore. Skipping the CI and
CODEOWNERSfences + would have been too daring. +
+ - Bob started to think harder about how to execute his work without breaking his contracts with Alice. +
- + Whenever Bob knew he had 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. + +
- + 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. + +
The monolith that wanted to couple
+ ++ 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. +
+ ++ 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. +
+ +A few consequences of this:
+-
+
- + 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. + +
- + 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. + +
- + 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. + +
The keys to the secrets
+ ++ 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. +
+ ++ 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. +
+ ++ 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. +
+ +The take away
+ ++ 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. +
+ ++ 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? +
+ ++ Is the solution to flip-flopping, mind-changing product owners to make messages containing the words "urgent", + "change" and "priority" undeliverable in Slack? +
+ ++ +