One of the challenges in a program is how you manage the checkins, especially if you have continuous integration. I am quite fond of continuous integration, no matter how large your program is. I also like short iterations. (Remember Short is Beautiful?)
But imagine a product where you have a platform and layers. I'm separating the GUI and the API for the GUI, so you can see the application and the middleware and the platform. Now, this architecture is different from separate-but-related products that also might be a program.
This is an archetype of an architecture, not your architecture. I am sure you have more than 3 middleware components or 4 app layer components. The product I'm thinking about had 12 middleware components, about another 12 platform components and about 50 app layer components. It was a big program with about 200 people working on the program for over 2 years. I wanted to simplify the picture so we could have a conversation.
The features cut through the app layers and the middleware layers. The colored lines are the features. Now, multiply these lines by each project team and each feature, and you can see what happens in a program. Imagine if I added colored lines for 25 features for 25 different feature teams.
It could be a problem.
However, if project teams limit their WIP (work in progress), and swarm around features, integrating as they proceed, they have fewer features in progress. And, if they are networks of people, so they have communities of practice, they have ways of talking to each other, so they don't have to wait to sync with each other.
People talk with each other when they need to. That's it. When features are small, and they integrate every day, or every other day, people expect to discuss integration issues all the time. And, while I am not a fan of integration teams, even I admit that on a large program, you might need an integration team to help keep things moving. This is in addition to what everyone does of syncing with the main line everyday: taking down the new additions to the main and syncing just before putting new changes up.
If you keep a stream of features moving in a program, even with many feature teams, as long as the project teams keep talking to one another, you are okay.
You are not okay if someone decides, “I own this code and no one else can touch it.” Now, you might decide that all middleware code or all particular component code has to be reviewed. Or it all has to be smoke tested. Or, it all has some other gate that it has to go through before it can be changed. Or you pair on everything. Or, you have situational code ownership. That's perfectly okay. You decide on the technical mores for your program. It's a good idea to have them.
But, the larger the program, the less you can have one gatekeeper. Because that person cannot be in one place, holding their fingers in the figurative dike. This is why I don't like czar-like architects, but I do like embedded architects in the teams for agile programs.
When the product reaches a certain level of maturity, you can work on a particular component as a feature, and swap it in or out once you change it as a feature. This takes significant skill.
If you want to be agile for a program, you need to be more agile and lean, not less. You need to have smaller stories. You need to work by feature, not by architecture. You need to swarm. Well, that is if you don't want program bloat.
Okay, what's confusing to you? What have I forgotten? Where do you disagree? Let's discuss.