Experimental fork based on C4

I will start by explaining how, in my opinion, your “experimental fork” is worse for maintainers, podmins, and users. I would not usually do that, because it’s kinda rude, but since you put in the work to show that off, I think that’s fair game. I’ll ignore things like the fact that you completely messed up the Git history by merging develop and next-minor in the same merge commit as a PR, but everything that has any relation to the ZeroMQ RFC is probably deliberate.

Your fork has merged 14 PRs that are not yet merged upstream. To comment on this, I have to put myself in the position of commenting on unfinished PRs as if they were meant to be production-ready. That’s not very fair towards those contributors, but oh well. That’s on you.

  • 7168: “Load initial comments in the SPV on pageload”. This PR has several review comments mentioning an inconsistent code style, several unnecessary additions, and no complete test coverage. This PR also has a performance impact on both the client and the server - both of which are already the cause of some slowness that is affecting end-users. Parts of this PR are not even needed anymore, because two of the three things mentioned have been addressed by other changes.

  • 7748: “stop ignoring from hovercards”. This PR has failing tests and violated our code style in multiple places. There’s also a review comment mentioning a race condition that yields an inconsistent UI state in 50% of the reviewers’ tests.

  • 7823: “Add a welcome email”. The email sent here has no plain text variant, which was a requirement mentioned. The proposed text uses several terms not commonly used by diaspora*, adding potential user confusion. There are also several concerns about a user potentially receiving multiple messages at the same time depending on the pod’s configuration, it sends emails to unvalidated email addresses (which can be a legal issue in some circumstances, especially after the CAN-SPAM Act of 2003).

  • 8037: “Remind the username in the reset password e-mail”. This has a change that causes a lot of translations to be invalidated with no good reason - this is a bit of a slap in our translators’ faces. There are also wording suggestions to make the message clearer to users because the proposed language might be confusing.

  • 8056: “Handle missing parent when deleting comment”. Good PR. Although we don’t know how often this occurs and if this is even a “real issue” or a weird edge-case, or not. No real harm done in merging.

  • 8203: “Re-introduce likes on comments”. The UI added here is inconsistent, as the like-links on comments are visible even if you’re not signed in, and on viewing posts on remote pods. There are also a couple of other things around that UI that probably could make it less noisy.

  • 8217: “multi select on aspects on mobile”. No idea about the state of that PR, probably fine to merge.

  • 8237: “direct image pasting”. Seems like there is some inconsistent behavior/undesired UX as explained in the review comment, to which no solution has been found.

  • 8242: “add a podmin mail to footer”. Probably good to merge. The comment added two hours ago is valid, but that was not there when you merged the PR.

  • 8246: “Let podmin send private messages to local users”. Some unaddressed comment, but probably not noticeable to anyone in the real world.

  • 8249: “Block/Close and wipe data for all accounts on local pod in admin UI” not sure about the state, looks like some architectural concerns are not yet addressed, but for the sake of this discussion, let’s assume this PR is fine.

  • 8277: “Add support for Markdown footnote syntax”. This PR had a concern about the understand’ability of the code and an architectural concern. This was recently addressed, but it was addressed after you merged the PR, so your merge is still the suboptimal solution.

  • 8280: “Cleanup person_by_handle route”. Good PR, no concerns here.

So, out of the 14 PRs you merged, I’d consider less than half “mergable without harm”, and that’s considering that I err on the side of “merging” if I don’t know details about a given PR. The other PRs have clear room for improvement. To our non-technical users, of which diaspora* has more than most of the other projects, diaspora* is known for and liked for stability and consistency. Changing stuff into a state where more polishing is clearly needed, adding inconsistent UIs or behavior, changing the wording in some instances because a change hasn’t been considered, … all those things violate the trust of our users.

In addition to the PRs, you also added some other changes:

  • You added a “production-ready” Docker container. There are several reasons why we think a “production” Docker container is not a good thing at this time, and you could have easily found them on GitHub and here on Discourse. You didn’t even base your container on our development-setup, but just copied an existing project that hasn’t been updated for three years. This includes exposing Unicorn to the frontend without reverse proxy (which s not what it’s designed for, and which also causes severe slowdowns because a limited amount of workers now also have to serve static assets, including images embedded from other pods). It’s based on Postgres 9.6, which has several severe downsides for use in diaspora* as compared to more recent versions, including huge performance issues. You also did nothing to assist podmins in upgrading between versions (stuff like running migrations, recompiling assets, … let alone somehow handling the manual changes required in some upgrades). This container doesn’t even work out of the box without manual intervention, because you don’t load the DB schema, or precompile assets (which is required in production). This is the kind of setup that looks easy to get started with, but then completely explodes on the first major upgrade, and then nobody is able to properly debug this, or sometimes even recover from the broken state. This is exactly what we want to make sure to avoid, and that’s also why there is no production Docker container yet.

  • You changed the version link to show the GitHub commit view instead of a clear and hand-written changelog. Sure, this makes it easier to simply merge PRs without any consideration or work, but to non-technical end-users, you just made it impossible to actually understand what changed between versions. And since you didn’t add changelog entries for the PRs you merged, you also made it impossible for podmins to understand what changed and to quickly glance if there are any critical changes that require manual intervention. (Edit: You reverted the link-change since the time the draft of this comment started. However, since you still did not add changelog lines for the changes you did, I still assume your intention is to not maintain that.)

  • You merged the develop/next-minor/main branches into one. This is consistent with the idea of C4 that says you should only ever have one branch and releases should be done with tags on the mainline branch. There is a reason why we use this git-flow inspired branching model, and it’s not just because we like the extra work this causes. :slight_smile: We promise our podmins that minor updates (and security hotfixes) can always be applied without manual intervention, and without long-running migrations. This helps a lot with pushing podmins to always stay on the latest supported version, which is relevant especially for security hotfixes. The small minor releases containing bug fixes and small improvements also help our end-users, because they allow us to ship updates more frequently. The develop branch will contain things that require manual podmin action, and sometimes database migrations that run for a long time, so we keep them separate. Not having that distinction and the associated promise will absolutely result in podmins updating less often, which isn’t a win for anyone.

  • You found it necessary in your process to comment “Bump on conflicting files” below five diaspora* PRs, and one insporation* PR. These comments don’t help anybody - they’re too vague for most contributors to be actionable, and they’re completely useless to maintainers because maintainers can rebase commits themselves if a conflict is the only thing blocking a PR from being merged (in fact, I’d argue that this is a maintainers responsibility if possible, or at least for the maintainer to assist). So far, this created nothing but extra noise and extra work, both of which you claim you wanted to reduce with your approach.

So with all that considered, I don’t see your fork as a net-positive.

Now, to the approach/idea itself. I can see some room for it working in a purely developer-facing project (like ZMQ), but I don’t see how that model is supposed to be reasonable for anything but that.

No, the key idea is that developers come first, and that’s pretty clear from reading the ZMQ RFC, your proposal, and from looking at your fork. Besides “it needs to be able to build”, zero consideration is put towards the end-users, because otherwise, it would be impossible to merge PRs with “passing” tests and “working” code but bad UX. Your statement is true if and only if your users are also developers. Sure, that is true for ZeroMQ, but it’s certainly not for a project like diaspora*. Project maintainers have to interface between users and developers, and also make decisions on behalf of the users. This includes blocking PRs based on suboptimal user experiences, which is something developers absolutely hate, but is necessary if you don’t want to scare away your non-technical users.

One thing I frequently see is people saying “I wonder why diaspora* became so big despite lacking so many features and flashy things”, and yet almost nobody considers “oh maybe diaspora* did become so big because it lacked a lot of the fancy things because the things that are there work surprisingly well”. Sure, this is a huge turnoff for some developers and for techies who always want the latest fancy tech, but maybe this isn’t the best for everyone. Each project has its own audience. A database administration tool will have a vastly different audience compared to a journaling tool. Their product decisions, and by extension their development processes, reflects that. You can get away with “oh let’s ship this feature even though it’s not 100% perfect yet, maybe someone will improve it in the future” opinions on a database administration tool, but you will lose users that way if you’re a journaling app. Making these distinctions, and consequently applying this to the entire project, is the difference between a project that’s dead, and a project that’s not.

I don’t know your projects, but in most cases, the answer is simple: nobody used your projects. If nobody is using your software, then nobody will have any incentive to improve your software. No matter how amazing and fluent your development processes are, if you don’t have an audience for your project, then it’s a dead project. For developer-facing projects, you may get away with it (given the project solves an issue that people have), but not for an end-user application. Suggesting a different development approach to boost an unpopular project isn’t solving anything. In fact, it might make the situation worse, because you might scare away developers who don’t like your approach.

I’ve been part of many mentorship/internship programs like Outreachy, Rails Girls Summer of Code, GSoC, … and one thing is very consistent: people are more excited and more motivated to work on a project that’s popular: either a code library used by a lot of projects or an application used by lots of users. And I see why, it’s just way more rewarding to see your work impact a lot of people.

Also, people generally like working on projects they themselves use. For a project like diaspora*, it’s far more likely that someone thinks “oh there’s a little bug here that’s annoying me, let’s submit a PR and fix it”, it’s unlikely that someone with no connection to the space of federated social networks at all will just pick up the project and work on it.

People don’t just submit a PR because they’re so happy today, they want something as a reward (even if that’s just unconscious): either self-interest in the form of changing something they use, or having the amazing feeling of affecting a lot of people.

To be quite blunt: This is one of the most toxic project-leadership ideas I’ve seen in quite some time. “Oh, you spent two weeks discussing an idea and another two weeks on implementing the agreed-upon proposal? Well too bad, someone didn’t like it and threw away your code.”

Healthy (F)OSS governance is not about who can yell the loudest or who has the most stamina. I’d probably go so far and say that the people who consider yelling loudly and out-stamina’ing others are probably the people you don’t want to have in your project. In a healthy project, everyone can make their opinions heard without being yelled at or without being just undone by someone who didn’t like something.

In its early days, diaspora* used a platform called Loomio to make project decisions. In essence, anyone could start a “thread”, explain their ideas, and then start a vote on that. If the majority voted “yes”, then that was the outcome of the decision. What sounds like a good idea at first turned out to be not a good idea at all. Very frequently, people realized their opinion was controversial, and then just used their friends and social media posts to tell people to vote “yes” on the proposal, effectively gaming the system. Frequently, very valid concerns were just ignored, because the vote resulted in “yes”, so clearly there was no need to discuss further.

In 2017, we decided to drop Loomio and set up our own Discourse instead, and with that, we rolled out several processes changes: 1.) There no longer would be a popular vote on anything. Instead, we discuss a topic for as long as there are concerns left to be discussed and until we agreed on an implementation. 2.) Large projects, like adding features or big refactorings, require prior discussion on Discourse. This is to avoid situations where we have to spend a lot of iterations on code (potentially wasting people’s time by having them start an implementation into the completely wrong way), and we usually feel relatively certain that we find the potential pitfalls of any given topic before running into them.

The move towards Discourse not only resulted in a lot of very healthy discussions between developers, it also resulted in a lot of our non-technical users starting participating here, asking questions, suggesting ideas, and participating in decision-finding processes. diaspora* has honestly been one of my most pleasurable (F)OSS experiences so far.

What you are proposing is kinda the opposite of all that. Instead of having thorough discussions before anyone spends time on coding, you want to reward whoever has the most time to spend on writing code and “overriding” others. Instead of allowing people to discuss an idea instead of code, you’re reducing an entire project down to its code. Your “don’t like it? Make a PR and change it!” completely removes the influence from anyone who cannot write code or does not want to write code. You even double-down on that in your second post (emphasis mine)

Because the only people who even have a chance to participate in that “competition” are the people writing code.

This alone is enough for me to actively dislike this proposal.

Your PR has a race condition that breaks 50% of the time? Inconsistent UX. Your PR adds a button that sticks out like a sore thumb? Bad UI. Your PR introduces a piece of text that uses completely different terms than everywhere else? Inconsistent UX. Your PR uses the programming language in a way that’s not used anywhere else in the project? Inconsistent codestyle. Your PR adds a feature that would raise some privacy expectations in users that can’t be met (my favorite example: “unlimited limited” posts)? Against the project spirit.

None of these things are even up for debate, they’re objective facts. And for the few cases where there is disagreement, well, that’s what non-code discussions are for.

Not really, tho. C4 does really not help to resolve the “unclear” and “subjective” parts of writing software. I mean, even you agree:

so ultimately, even for the “unclear” parts, C4 cultivates an environment where those people who can yell the loudest get their wishes fulfilled.

I once had a contributor implementing a feature. It worked great, they even had an instance set up to demonstrate how great their feature worked. They even wrote tests. The problem with the patch was, though, that they completely lacked any federation implementation, so everything happening around that feature would be pod-local only. It worked for them, and they had no interest in adding federation support. So, is that a “correct” patch? It solved their issue, and it was the “minimalist” solution to their problem - yet I’d argue that merging something like this would be more than ridiculous. And while this is an extreme example, the lines are a lot more blurry than you make them look like.

Quoting the C4 ZMQ RFC:

a minimal and accurate answer to exactly one identified and agreed problem

This itself is already unclear and undefined. How does one “agree” on a problem if project governance happens on code? How do you define “minimal”? This is already where everything falls apart, and is back to completely subjective decision-making, but this time, it’s the contributors’ job to try to talk their way into having something merged.

The user or Contributor SHOULD seek consensus on the accuracy of their observation, and the value of solving the problem.

The fact that this is a “SHOULD” and not a “MUST” also makes the whole protocol kinda weird. So it’s fine to submit patches where I did not seek consensus and it’s fine for me to expect that to be merged? This sentence alone is so incredibly vague that “C4 takes the unclear parts out of the process” is simply not a true statement.

Any Contributor who has value judgments on a patch SHOULD express these via their own patches.

This is what I already described above: gatekeeping project participation to only people who can write code. This turns any project into a nerdfest that completely leaves out the actual users. If you tell your users that they’re not allowed to voice their opinion unless they learn to code, then it’s no wonder your projects don’t have users.

Maintainers SHOULD close user issues that are left open without action for an uncomfortable period of time.

Just because an issue has not been resolved does not mean that an issue is invalid, or not important. Discarding user feedback just because it’s “too old” is absolutely disrespectful towards those users who take the time to report an issue in the first place, potentially even creating a new account on an unfamiliar platform to do just that. Again, that’s good if you want to turn your project into a nerdfest, but it’s bad for literally everything else.

Also, what is uncomfortable? If I’m a user reporting an issue that deeply affects my workflow, a week feels uncomfortable. If I’m a maintainer working on my side-project with little time left, multiple years is perfectly fine.

Edit wars on Wikipedia are not resolved through competition. The exact opposite is the case. The Wikipedia rules on Edit Warring explicitly states (emphasis mine):

Editors engaged in a dispute should reach consensus or pursue dispute resolution rather than edit war. Edit warring is unconstructive, creates animosity between editors, makes consensus harder to reach, and causes confusion for readers. Users who engage in edit wars risk being blocked or even banned. An editor who repeatedly restores their preferred version is edit warring, regardless of whether those edits are justifiable. Claiming “My edits were right, so it wasn’t edit warring” is not a valid defense.

The reason Wikipedia has this rule is because they try their best to avoid being a toxic hellhole. Just overwriting someone’s changes with your own because you feel like you are right is not a good thing. If you override someone’s first contribution, they’ll likely just go away and never contribute again, because they’d rightfully feel disrespected. And if you’d revert the edits from someone experienced, then they might just enter an edit war, and the ultimate winner would be the one who can waste more time reverting changes, not the one who has done more research on a topic or who has the better language skills. This is neither productive nor improving the project’s output nor a welcoming environment for anyone.

Every article on Wikipedia has a discussion page, where you can discuss changes before doing them. You can also reach out to individuals by writing on their userpage or sending them a message. All of those things are there to seek consensus before wasting any time writing a “patch”. Just like any healthy open source project, Wikipedia is about collaboration, not about competition. And if you have a different opinion and you try to turn Wikipedia into a competition, then “maintainers” will show you the door.

diaspora* is not a project to be “installed once and run for years”. We frequently release security hotfixes, and not installing those is gross negligence. Before most of the work was focused on finishing the next major release, we pushed regular minor releases in a fixed 6 week period, with a pre-defined schedule. This was done, amongst other reasons, to have users get bugfixes faster, which has a strong impact on user happiness. Having a somewhat predictable schedule, paired with the promise that minor releases won’t be painful, makes the project have a nice velocity that allows users to receive improvements fast while keeping the maintenance efforts required from podmins low.

Yes, this requires the “release branches” to always be in a perfect state. However, everything else is not an option for a project like this. In this project’s past, we’ve had quite a few things that have been controversial before being merged, which then were merged “unpolished” with the promise that it will be polished after merging, and then… the feature being removed a long time later because it was still buggy and broken and unfinished. This was not a surprise to anyone, especially since the lack of polish and the lack of maintainability have been a concern for those people voicing criticism from the beginning. How exactly do you think your “just file follow-up PRs to polish things” will work out? Who do you expect to do that polishing work? If the original contributor is expected to do it, then they could do that work in the initial PR. If it’s not the contributor, who is it? Another contributor? Nobody wants to clean up other people’s mess. The project’s maintainers? That’s a great way to burn out maintainers. (Ask me how I know.)

For diaspora*, the policy so far has been “if you add a feature, then you have to own it or you have to raise enough support that core maintainers are willing to support it”. This has resulted in some frustrated contributors, and lots of “omggg why is X not done yet???” threads, but it also has resulted in a piece of software that is appreciated by users because it’s not in a neverending state of half-brokeness and constant UI change. Yes, this also means that some features lay around in the PR section as half-finished patches. Sometimes, someone else picks up a PR and finishes it, because they want to use that feature (which is great, because then they’ll also fix it if things break). And sometimes, this means that things don’t get done. This isn’t awesome, but I’ll take that any day over explaining the people on my pod why so many things are only half-working and why things they use every day change every other day.

Nothing about the idea of merging patches with fewer expecations, or even automatically merging patches, is new. The idea is probably as old as collaborative software development itself (heck, I remember a very old discussion on LKML proposing exactly that), but the reality is that this simply doesn’t universally work. ZeroMQ is a set of projects with relatively low complexity, and with an audience exclusively consisting of software engineers. And even for ZMQ, I’m not sure how well it actually works. Even with their limited audience, limited complexity, and “defined” “processes”, there are bug reports/feature requests open for 6+ years (<- that one actually had me stop using libzmq), and there are PR-chains going for more than two years that could improve libzmq a lot, but nobody really cares enough to do all the work alone and the process seems to actively discourage collaboration. So, sure, on a surface, it seems to be somewhat working for them, but if even they have issues following their own rules, … well.

This is less about “being skeptical”. This is more about using years of (F)OSS experience to gauge what works, and what won’t work. C4, and any ideas similar to this, simply don’t work in most environments.

3 Likes