How can I address the concerns of the software architect but still maintain collective code ownership?
I'm probably bikeshedding, but that's not your problem. The company owns the code, not a developer or an architect. Everyone works to better the whole. You have problems in your engineering process, and it's resulting in a blame game later.
You need to determine the cause of the failure (failed self test and broken components), and put policies and procedures in place to address the gaps. Once the policies and procedures are in place, there's no one to blame because "things just work".
In the current situation, developers change code in multiple components and they break other components either because they don't understand how the component works (because they work with so many components) or because they don't care about how their changes will affect the other clients of the component (as long as they are not affected).
Perhaps there's a third: the developers don't know they've nudged or broken code in other components.
That begs the question: what is in your engineering process to address the gaps? Are there policies and procedures in place to catch the problems early?
I can say for certain that liberal use of
ASSERTs (as opposed to POSIX's useless
assert) will ensure a developer knows about nearly every unexpected condition at development time. I call it "self-debugging" code, and I spend nearly no time under a debugger because the code tells me where the problems are.
When I say "liberal use of
ASSERTs", I mean everything. You assert all parameters are expected when entering a function. You assert all program state used in a function. And you assert all return values from system calls. If there's an
if to validate something, then there has to be a matching
ASSERT. If there's an
ASSERT to validate something, then there has to be a matching
if. The code will not be able to fart or sneeze without a developer knowing about it.
Another way to look at it: why should you debug my code, and why should I debug your code? Let the code debug itself and tell you where the problems are.
Another way to look at it: why should you spend time debugging? Your time is better spent on adding features. Let the code debug itself and tell you where the problems are.
If you have not studied how to ASSERT, then it would a treat to read John Robbins. He is a master bug slayer. The book I learned from was Debugging Applications. His blog is at http://www.wintellect.com/blogs/jrobbins.
There must be complete self tests for components. I don't waste a lot time on the positive self tests. I can hire a kid from India or Pakistan for US$10 a day to copy/paste code that works as expected under benign conditions. Rent-a-Coder is full of them.
I focus on the negative self test. I want to know how the program fails and ensure it recovers or fails gracefully. And when I say testing, I mean testing everything - even protected and private interfaces in a C++ class.
I don't buy into the arguments that "only public interfaces need testing". Hogwash until someone produces a program without bugs. I've got code in the field that goes years between bug reports because my engineering process requires 100% coverage with negative test cases.
Continuous integration into a staging area. Every commit kicks off a build and self tests. Reject the check-in if it breaks a build.
The Real Gem
The real gem in the three processes above is you don't need expert coders. You can hire interns and junior developers to instrument code with
ASSERTs and write test cases. I would even argue you need fewer expert programmers because the code is doing the heavy lift by debugging itself. That should make management happy.
And your expert developers will get pissed off when a junior starts breaking their code in obvious ways. I can't tell you how many times a guys with 10 or 15 years of experience complained to me about all the damn asserts that are firing. It's amazing what you find when you start looking for problems in code you thought was solid.