Like everything else, the answer is, it depends. In this case it depends on what you mean by code ownership. Because code ownership can mean different things to different people. In this case I'm not talking about who owns the intellectual property. I'm talking about the responsibility for code. Not just writing, but maintaining and extending it.
There are a handful of models to choose from. The simplest is strong individual ownership. For any given piece of code (application, library, module, service, etc.) there is exactly one person who owns the code and is solely responsible for making changes. That works. Clarity is always good, and you always know who's on the hook to make something happen. But it's less than ideal when you actually want things to happen. Especially if there is more work than the designated individual can do. That person becomes a bottleneck.
Another option is team or small group ownership. In complex systems this brings the benefit of reducing cognitive load while mostly removing the bottleneck(s) of individual ownership. If you're not part of the team you just make the function/network call and assume it's going to work. You don't know or care what's on the other end. You just do your day job and throw problems/issues over the wall and the team will pick them up and deal with them. It does make your job easier, and, because there can be multiple people working on the other side of the wall it is much more scalable than individual ownership. But the team on the other side of the wall isn't infinitely growing, and you're probably not the only one throwing things over it, so when your issue is dealt with is still pretty undetermined. There's still a bottleneck, but it's not as bad as it was.
Then there's collective ownership. Everyone owns everything. Have a problem? Just fix it. Don't like the way something works? Fix it. Need new functionality? Add it. After all, we're in a monorepo, so it's easy and it solves your needs. Perfect. Or not. Everyone owns everything is just another way of saying no one owns anything. That's anarchy, and we certainly don't want that.
Personally I'd like to see a modified version of team ownership. Reducing cognitive load is important, so I strive for that. And complex systems are just that, complex. Unless you've been thinking about something deeply for a long time there are almost certainly strange interactions and emergent behavior in a system you need to be aware of when making changes. And the only way to get those insights is through experience. So team ownership, as in responsibility for how the sub-system fits into the greater whole, makes a lot of sense. The team knows the sub-system, the tools, the customers, and the gotcha's. They're usually the right ones to make changes, so they should do it.
But not always. Sometimes they're busy. Sometimes your priority isn't theirs. Sometimes they don't understand you. In those cases the right thing to do is make the change yourself. Then make a request to the team to pull your changes in. A Pull Request if you will. Then the team can evaluate the PR, bringing their experience and plans to the evaluation, and then accept the change or make suggestions about how it can be improved. And they need to do that quickly. They might even iterate directly with the author of the PR to make sure it meets even more needs than the author had originally intended. And that's good for everyone.
Or, in other words, we're all responsible for getting our own work done, and sometimes that means making changes to parts of the codebase we don't normally work in. And in those situations we're all responsible for working with the experts in that area to make the right changes, not just the changes that benefit us, regardless of the cost to others.