Eons ago(2006, to be exact), Martin Fowler outlined three types of code ownership: strong code ownership, weak code ownership, and collective code ownership. Strong code ownership involves modularizing parts of code and assigning each module to a specific developer. The developer would then make changes to that module alone. Modules that are slightly dependent would require the developer to have to communicate changes made. If a developer wants to make changes to modules he/she does not own, he/she would have to send requested changes to the the developer that owns the module.
You can start to see how problems may arise with this form of code ownership. You may have a situation where the bus factor comes into play: what happens when a member of that team suddenly quits and leaves behind months’ work of undocumented code? Martin’s point was that strong ownership was deeply problematic due to the fact that communication issues could hinder development speed.
There are just too many situations where something you need to do needs changes to other people’s code. Persuading them to make the change and waiting for the change often takes so long that it leads to delays and deeper problems, this is particularly galling when the change is a simple one.
Weak code ownership loosens the restrictions a bit by allowing developers to make changes to the modules of other developers while collective code ownership does away with individual ownership altogether. Whatever type of code ownership a company chooses to employ, there will be pros and cons. Examining a Hacker News thread, I was able to get a general sense of the type of code ownership being practiced today. Here are developers’ takes on the type of code ownership that their company uses.
In our case, teams don’t own projects/code-bases, they own “features” and “releases”.
About 67% of our code is some form of Ruby – some of it Rails, some of it custom Ruby code running in Kubernetes+Docker processing data.
The other 33% of our code is Rust – and not just service side code but Rust that has to run on multiple platforms with varying deep operating systems knowledge.
My team generally owns Features and Releases related to the Rust code because two of the three members are OS programmers by experience. That said, we don’t exclusively work on the Rust code and sometimes wander into the Ruby code base.
Similarly, other teams occasionally need to update the Rust code to generate some new data – a lot of that is pretty basic stuff and doesn’t require deep OS knowledge. So they’ll make changes there.
Since our stack is so heterogenous, it’s hard to have everyone work on everything. However, from what I know of most companies outside Apple/MSFT/Google/etc, they’re gonna fall in the “we own web services” where the only real bifurcation will be “frontend code” and then “middle-to-backend code”. Maybe throw in some apps as well.
Now all of that said – the reason we went to teams owning “features” and “releases” was to push folks to not be possessive of code. Stuff changes and it changes quickly, so there’s not much use trying to isolate folks. Document gratuitously, test heavily, and refactor often.
In my experience with several big organizations (20,000+ employees), they tend to have a home-grown application to track ownership of resources (assets) – including source code (repositories), and servers, databases, scheduled jobs (in autosys or suchlike).
Generally each of these entities is grouped into some bucket for an application / “system” / business area, and then that bucket has a few owners assigned, and also other non-ownership roles assigned (developer role can check in code to those repos, prod support role can log into the servers owned by the bucket, etc).
It’s generally heavily integrated with an LDAP directory, HR system to handle joiners and leavers, and also change management (Developers can only ssh to a production host during the change window of a change for that bucket).
These home-grown apps are generally old and clunky (written for IE6, with piecemeal improvements since then, that kind of thing), but hard to replace because they’re integrated with so many other applications.
I tend to think that this would be a good opportunity for some (startup) to do a great job of this as an off-the-shelf product, with good integrations with Linux + Windows authentication, an API, nice web app, etc – it would be very easy to do better than the in-house systems filling this niche.
At my current workplace, most top-level subdirectories in the source tree have a primary author. That person is (nominally) “owner” of that code. If they aren’t the one making changes, they’re almost always at least the one doing the code review.
Bugs by default get routed to the person who wrote the code (presuming that we can tell which code the bug is in). If that person finds out the bug is somewhere else, the bug gets transferred to a new owner.
I work for a large global company, and my department is building a fairly large Angular application. My team “owns” the primary project and several shared component libraries, and other teams build features for this project.
These teams are from all over the world, and many of us have never worked closely before this project began.
When we first started the project, we decided to split the UI into feature projects which are packaged and referenced in the common project. Each team owns their own feature projects; however, everyone is welcome to contribute PRs to any of the projects.
Some of our projects are shared and maintained by many teams, but we always have one team that owns each project.
Ideally you want to restrict changes to the owners (I don’t mean hard limits) So instead of having a team responsible for a part of code, they are responsible for the product. So if a new integration is needed, the owner is a service provider and should provide the interface or service for their client. That is fairly easy to setup with Microservices. However, that is a bit harder in a monolithic application code base.
In my workplace, we use the above model for almost everything. And there is one old code base where we use Github code ownership feature to force everyone to ask for a code review from owners. But even there, it doesn’t happen very often that people from different domain need to touch a code of another domain.
And that is the second point as well. Dividing responsibilities base on domains instead of components/modules between teams make it easier as most of the time they are not going to touch a code outside their own domain.
Everyone “owns” the code. Then there’s the guy you go to when it fails.
Helps to document things, so you at least have something to throw at people when they come asking.
Overall, collective ownership seems to be the dominant form of code ownership. The line between weak ownership and collective ownership begins to blur a bit when a code base is split into features where ownership is temporary. Even then, a subset of teams claim a collective ownership over a feature. The size of a company also seams to effect the type of ownership used. For example, a company that gives complete ownership of debugging to someone who is on call can do so if they’re company has 20 or fewer engineers. Once the number of engineers balloon in hundreds, then a collective ownership is needed to maintain productivity.