The last time I wrote about the .NET Foundation was in the context of the “Project Maturity Ladder” proposal in late 2019 - a well-intentioned, but ultimately not really appropriate measure aimed at trying to increase the adoption of best practices among member projects.
The .NET Foundation has its heart in the right place - widening the range of “acceptable” OSS beyond what is produced in Redmond. I want that too. Everyone does, most of all the developers who aren’t able to use that OSS today because of the historical conservatism of the .NET ecosystem as a whole when it comes to OSS.
The current proposal puts the .NET Foundation as a centralized certification authority for the entire .NET ecosystem. That’s heavy-handed and will ultimately undermine the .NET ecosystem’s ability to become “bigger than Microsoft.”
The key takeaways from that saga, which is still recent in the minds of many maintainers who are participating in this week’s public outrage against the Foundation:
- The .NET Foundation did not build any agreement with member projects before introducing the maturity ladder proposal, so it came as a surprise to its member projects;
- The .NET Foundation appeared to be pursuing some different priorities than those of the member projects itself, the former pursuing continuity of business and professionalism of the projects whereas the projects themselves are much more focused on supporting themselves and reducing costs; and
- In general, the .NET Foundation’s top-down approach to trying to manage the ecosystem wasn’t really aligned with maintainer’s expectations (set by the Foundation itself years earlier) of a bottom-up, collaborative federation of projects. Too much Cathedral, not enough Bazaar.
I issued a warning at the time that going down this road of treating member projects like they’ve automatically agreed to whatever the Foundation leadership decides to do by the virtue of joining it will lead to misalignment between the two groups of stakeholders. In other words, agreements have to be constantly renewed among the members - otherwise there will be less cooperation, less trust, and a lot more public pushback.
Two years later and it’s clear that the .NET Foundation did not learn these lessons.
I’m going to address this in three parts:
- Summary of the current kerfuffle;
- Paths forward for the .NET Foundation and its projects; and
- Aspirations for the .NET OSS movement.
I won’t go into all of the details here, as there’s a lot of them, but I will provide a short summary:
- The .NET Team, a large organization run by Microsoft that is also part of the .NET Foundation, created a tool designed to make it easy to ban Code of Conduct violators across their entire Github organization. .NET Foundation leadership thought it would be a great idea to also ensure that all Foundation member projects, including ones not run by Microsoft, subscribe to this system also. If you get banned from any .NET Foundation project, you get banned from all of them that subscribe which has the practical effect of removing control from maintainers to run their own communities - this touches on the larger issue that set off this debacle: project autonomy.
- The .NET Foundation normally has administrative access to its member projects, for continuity reasons, and used that administrative access to setup this CoC enforcement for foundation projects. In cases where projects had not yet granted the DNF administrative access, the Foundation requested it expressly for this purpose.
- Member projects who granted this administrative access also, suddenly, found themselves transferred off of the public GitHub they’ve been using for years and moved onto the .NET Foundation GitHub Enterprise Server without any notification. This, in effect, broke things such as Github Sponsors - and the extent to which organizations were moved by the Foundation was not really known until this week.
- There’s other questionable behavior and miscommunication at work here too, and I sourced that together in dotnet-foundation/Home#38.
- The .NET Foundation Executive Director issued a public apology.
- The .NET Foundation Executive Director tendered her resignation to the board and it was accepted.
There’s a lot to unpack here, but the real issue is fundamentally who owns the projects in the Foundation? The maintainers who work on the project every day, myself included, were assured that we would be “left to run ourselves” at the time when we joined. What “run ourselves” means appears to have changed over the years.
Project Administrative Access: The Nuclear Option
It’s a given that the .NET Foundation should probably have administrative access to these projects to remedy situations where a maintainer abandons a project or becomes incapacitated - even though GitHub supports account successors in this event. Administrative access should also be used in the event that a maintainer abuses their authority, i.e. begins distributing malware or adware in a trusted package.
But using that administrative access is a nuclear option - OSS foundations must have it but they must also never use it outside of these narrow cases. As soon as you make a move using this access without the maintainers’ consent the fallout is going to turn the relationship between foundation and maintainer radioactive, as the maintainer’s autonomy over the project is now compromised.
This administrative access was used both to silently outsource projects’ community management of its own membership to an unaccountable, centralized .NET Foundation Code of Conduct enforcement system and for moving the GitHub organizations to a piece of infrastructure controlled by the .NET Foundation itself. Both of these were exercises of this nuclear option for member projects even if those projects would have likely agreed to do both voluntarily.
That’s the source of the project maintainers’ alarm and outrage: the .NET Foundation usurped our autonomy over our projects without our knowledge or consent.
The Sticky Wicket of Ownership
The .NET Foundation Executive Director issued a public apology that primarily fixated on one of the smaller issues that kicked this kerfuffle off: merging her own pull request over the objections of the maintainers in a member project. This lead people who aren’t familiar with the situation to conclude that what most maintainers were angry about was one pull request; no, that’s absolutely not the case.
The larger and more fundamental issue of the .NET Foundation’s use of its administrative access to member projects wasn’t addressed to anyone’s satisfaction - and moreover, was made ten times worse when the .NET Foundation asserted this:
It is also clear that the .NET Foundation project governance model is not well understood. Project maintainers sign an agreement that either assigns or contributes their project to the .NET Foundation. That’s the point at which project ownership changes. We’ll post another document on that this week as well.
There is a pattern that needs to be resolved. Projects might not fully understand what joining the .NET Foundation means. We share a checklist with project maintainers on project changes they accept as part of becoming part of the .NET Foundation. That’s obviously not sufficient. We will post a new document that describes what you can expect when your project joins the .NET Foundation. This will include changes (observable or legal) and new benefits. It will also include changes that could occur later.
As I put it in the comments:
Myself and my fellow contributors own and manage the project, not the .NET Foundation, as is plainly stated in our agreement. On what basis can you make this claim? I think you have this exactly backwards - the expectation that was set with us that we were to be left alone to our own devices, that the .NET Foundation would support our efforts to build a bigger and better .NET, but that ultimately we were to be in charge of how we did that. It seems to me that your vision for how the .NET Foundation will execute that is what’s changed - a top-down, command and control approach rather than a collaborative approach with us and our projects.
The issue of “ownership” of an OSS project is, by design, sticky. There are two dimensions to it:
- Legal - who holds the copyright, trademarks, patents, and other brand assets and
- Practical - who has the ability to accept changes to the source, publish + distribute releases, run the projects’ infrastructure, and communication channels.
Open source licenses are designed to make it progressively harder and harder to change the license and copyright of the source code the more people who contribute to it - this is meant to act as an insurance policy to protect the users and preserve the project for future contributions.
Open source projects that join nonprofits such as the .NET Foundation either contribute or assign their copyright to those foundations in order to safeguard the contributors’ body of work in perpetuity against potential legal liability and intellectual property disputes - it’s somewhat ironic then that the projects find themselves in need of defense against the .NET Foundation itself.
Under the contribution model, the .NET Foundation doesn’t actually own the copyright to the source code - it’s simply granted a perpetual, irrevocable license to it and the maintainers agree to change the copyright header to match the .NET Foundation going forward. All contributors still own their contributions and can also grant licenses to their work to other organizations under the same terms - as defined by the project’s OSS license.
Under the assignment model the .NET Foundation holds the copyrights and essentially owns the source. It’s worth noting that one of the recent bones of contention between maintainers and the .NET Foundation is that this form of contribution was silently removed from the website and then added back two hours later without much explaination, leading many maintainers to conclude that this was a move the Foundation was contemplating in order to exercise more direct ownership over member projects. That episode passed without a lot of public pushback - but there were privately expressed concerns from maintainers.
In either case the IP protections the nonprofit holds don’t do anything to prevent users from forking the source code and redistributing it under the same terms as the original license. That’s the beauty of open source - it can’t really be “owned” under most licenses.
The practical ownership issues are what really impact day-to-day operation of projects - if I run into an urgent issue that impacts some of my users, I need to have the ability to push a new release on a time-frame that is solely determined by our project. Most OSS foundations do a great job at accommodating this and get out of their projects’ way - the .NET Foundation, on the other hand, has a recent track record stretching back to the maturity ladder of becoming more heavy-handed in this regard: demanding that projects implement specific licenses (i.e. not all OSI approved licenses are acceptable), specific API design guidelines, release guidelines, code of conduct enforcement, and more. You can also read more from Glenn Watson’s post about how the DNF blocked his project’s ability to publish releases for three months and was generally non-responsive until there was a public uproar - this is precisely why projects are hesitant to rely on the .NET Foundation’s infrastructure: relying on a non-responsive .NET Foundation bureaucracy for tech support runs counter to the maintainer’s desire to publish releases when it suits the project itself.
What further compounds this issue is the .NET Foundation’s relationship to Microsoft; the Executive Director is a full time Microsoft employee and always has been; the .NET runtime itself is the largest member project in the Foundation; and there are permanent .NET Foundation board seats granted to Microsoft employees .The .NET Foundation is technically independent from Microsoft but it’s impossible to ignore Microsoft’s singular influence on it. The practices that the .NET Foundation is recommending its projects adopt are identical to the best practices Microsoft itself upholds. The needs of the .NET runtime are not the needs of the .NET community.
That is the major source of tension between the Foundation itself and its member projects: the expectation when we joined is that we’d be left alone to our own devices. As Dave Glick put it:
This is where I believe the core misalignment is happening. The community is very loudly saying “the things you are doing, regardless of their intent, are not what we want or need from the .NET Foundation” and the .NET Foundation is responding with “we’re going to continue doing those things you just told us you don’t want or need, but we’re going to communicate them better so you’re not surprised about us doing things you don’t want or need.”
Projects didn’t join the .NET Foundation with any expectations of becoming gang-pressed into what looks and feels like a Microsoft product management regime. That was one of our original objections two years ago with the maturity ladder and it still, clearly, has not been genuinely heard by the .NET Foundation.
But casting a pall over who “owns” the Foundation’s projects in the midst of an apology for transgressing those same projects’ boundaries? This is one of the most spectacular public relations backfires I have ever seen. If I was in .NET Foundation leadership and was asked “how can we make this situation as toxic and prolonged as possible?” - hanging the specter, however remote, of having the .NET Foundation pursuing action against its own OSS projects run largely by uncompensated individuals is exactly what I would recommend. That a team of people inside the .NET Foundation collectively crafted this apology and this was what they came up with illustrates the full extent of the communication problems plaguing the Foundation.
Paths Forward for the .NET Foundation and Its Projects
That’s what has happened. What could happen next?
Heading for the Exits
So the Executive Director of the .NET Foundation has already resigned, which is the right move.
No one doubts that the intentions of the officers and board members are good; this is not Embrace, Extend, and Extinguish 2.0. There are no “bad people” here - the same goes for the rabble-rousers participating on the thread. But well-intentioned or not the damage has been done under their watch and their attempt to clean it up via disastrous apology did not instill confidence that things will be any different moving forward. Calling for leaders to exit from the Foundation is an implication of their on-the-job performance, as that’s what is at issue, not character.
It’s also worth remembering that this did not happen in a vaccuum - what role did the Foundation Board have in overseeing these decisions? Why did no one on it think to reach out to member projects to see if any of this was a good idea? That’s a communication and oversight breakdown that must be investigated before the projects and the Foundation can move forward.
What happens to the Foundation and its projects?
- Immediately define a clear and unambiguous 1-page “Mission and Purpose” document for the .NET Foundation and a separate document outlining the set of standards that all projects must agree to in order to remain in the Foundation.
- Change the Foundation bylaws to include language granting Foundation projects themselves voting rights to approve or disapprove changes to those standards going forward - no more leading by fiat. Regular agreement building and rebuilding needs to become habit of the foundation; if it wants to operate by the letter of the law, build the cadence of communication directly into it.
- Update the Foundation bylaws to restrict what the Foundation’s administrative access can be used for: continuity or, at the explicit request of the project, help setting up project infrastructure. In the event a Foundation member with that access ever uses it for any other unauthorized purpose, as can be proven via audit log (n.b. moving projects onto GitHub Enterprise left nothing behind in the audit log - which is a major problem,) they are immediately terminated and permanently banned from the Foundation.
- Before imposing the new standards and mission, every project in the Foundation has to re-apply. If a project chooses not to the Foundation agrees to not fight them on the way out. All agreements are rescinded; all property (i.e. domain names, trademarks) returned. This also gives the Foundation a chance to kick out projects that don’t serve its mission or meet its quality bar. Everyone wins.
All of these proposals should be presented in draft form in public for comment - “work in public” is the default in OSS. The .NET Foundation needs to embrace that too.
This is the fastest way to restore trust between all affected parties, as it:
- Resets expectations unambiguously, resolving the largest specific communication problem that has plagued the Foundation for years;
- Actually makes member projects equal partners in decisions that affect them and forces Foundation leadership to get in the habit of persuading, rather than coercing, its members; and
- Acknowledges the damage done, recognizes that the path forward isn’t workable for a non-trivial number of projects, and resolves the negative impact by not fighting the projects on the way out.
It will take years to restore trust in the Foundation, but a change in leadership + clarification of mission + exit ramp for people who just want out will cut the time to heal significantly and quickly.
If this does not happen, the path forward will remain hostile between both sets of stakeholders and the .NET ecosystem will suffer for it, which neither group wants. An exit will likely happen the hard way - with maintainers forking, renaming, and re-branding their projects. The path of the hard fork is labor-intensive and strenuous, but people aren’t going to work with an organization they fundamentally don’t trust to act in their best interests. This is a fact and the stakeholders at the .NET Foundation and on the .NET Platform Team, the most powerful project in the Foundation, should come to terms with it quickly.
Future Mission for the .NET Foundation
So what should the mission for the .NET Foundation be moving forward?
- Consumer focused: the Foundation becomes much more closely aligned with the .NET platform itself and serves to be the non-profit evangelism arm for the runtime itself - basically, a home for Microsoft’s projects and a handful of other cornerstone projects (i.e. FluentValidation, xUnit, NUnit, etc). All projects follow the maturity ladder / .NET API best practices here. This comprises the bulk of the Foundation’s outreach and education activity today - hence the emphasis on creating meet-ups, speaker directories, etc. Most third party projects leave under this scenario.
- Producer focused: the Foundation goes down the road of prioritizing increasing supplier diversity in the ecosystem - make .NET bigger than Microsoft. Priorities include helping member projects professionalize, establish more efficient OSS operations, provide infrastructure, provide graphical help, provide legal help, create free resources (i.e. DocFx themes), and work with projects on growing their human capital through sustainability initiatives. Under this scenario most third party projects would remain onboard in the Foundation.
The .NET Foundation’s problem today is that it tries to be both of these things and serves neither audience well in the process. Constant public uproar with its own OSS projects detracts from its consumer-focused mission. Prioritizing what .NET consumers, especially large companies, need to trust .NET OSS detracts from more urgent priorities that impact Foundation projects, namely growth in human capital and sustainability.
Making the priority clear will be liberating for all involved. Both options are equally valid and important.
Aspirations for .NET OSS
The .NET Foundation may yet be saved, but the .NET Foundation is not .NET - which is doing fine and is vibrant, at the moment.
I have written numerous posts about the state of .NET open source, some of which are critical and some of which are quite supportive of what they’re doing. My priors are that I love the .NET community and have dedicated Petabridge to growing it. Despite my harsh criticism of the Foundation, you would be mistaken to interpret it as anything other than the defense of a technology, movement, and community that I love.
The people on the other side of this .NET Foundation debacle almost certainly feel the same way. It would not sit well with me if they were discouraged from participating in the .NET ecosystem going forward. The pillar of our OSS movement is its need for growth; we can’t let arguments, no matter how heated, about direction and governance push people out of the movement. Forgive and move on once this is resolved.
In the longer term it’s healthy for our ecosystem to have more .NET projects participating in open source foundations independent of Microsoft. Maybe that means having projects become part of the Reactive Foundation, CNCF, Apache, and so on. Maybe it means the creation of new .NET-specific foundations that are member-lead. It’s healthy to debate the role that various institutions will play in the future of our ecosystem.
We are still at the dawn of cross-platform, higher performance, run everywhere .NET. The limit for what we can achieve with our technology is our imagination. Things are much, much better for .NET OSS today than they were when I documented the state of .NET OSS seven years ago. That’s why I remain optimistic about the .NET community at large and look forward to putting this episode behind us so I can refocus on our users, customers, contributors, and code.