See PHI1313. Currently, when you have project A and create subproject B, you get prompted to irreversibly convert A into a "parent project" with no members:
The fundamentally irreversible nature of this operation causes various kinds of friction. Although the documentation explains things fairly clearly, this is one of a very small number of irreversible operations, and we try to write the software in a way that doesn't require you to carefully read the documentation before you do anything. We also generally teach users that clicking things is OK by having almost everything be safe.
The reason things work like this is that if we have a project tree like this:
- Farm Animals - Dairy Animals - Cows - Sheep - Goats
...and write an access control rule like "Can Enter Barn: Members of Farm Animals", we don't want "Betsy the Cow" to need to be added as a member of each level of the hierarchy explicitly ("Farm Animals", "Dairy Animals", "Cows"). When we say "Members of Farm Animals", we clearly mean all the cows, sheep, and goats.
This means that the effective members of "Farm Animals" need to be the members of all subprojects.
However, we go further than this and prevent "Farm Animals" (or any other parent project) from having any direct/explicit members. The rationale is that this makes it harder to make mistakes and makes the model more clear: if you can still be a direct member of "Farm Animals", we can run into cases where "Betsy the Cow" is a direct member of "Farm Animals" and also a member of "Cows", which is likely somewhat confusing/inconsistent. I think this behavior generally improves clarity around the rule that "Members of Cows are also members of Farm Animals".
It also makes "correct" subproject operations (where you're splitting an existing project into subprojects, and know exactly what you're doing) a little easier by doing a member migration for you. For example, if your farm only has Goats and you want to add some Cows, this behavior lets you add a new "Goats" subproject, move all your Goats into that subproject in one go, then define a Cows subproject and add cows.
However, this behavior also has some downsides:
- When you create an initial subproject, you're forced to migrate, even if you don't want to (or don't know if you want to, or don't fully understand the operation since there's a nice blue button to click instead of 5 pages of very technical documents).
- If you "Convert Project" by mistake, or without a complete understanding of how parent projects and subprojects work, you can't go back.
- PHI1313 cites a case of users doing the conversion by mistake, then being stuck with "Cows" as a parent project and a "Cows_MEMBERS" subproject to add members to the project.
It's very possible that the downsides of this behavior outweigh the benefits, and worth considering changing the rule so that parent projects may have direct members.
If we do adopt this, then under the new behavior, if you do want a nice clean hierarchy, you can always set "Joinable By: No One" on the parent projects and imply the current behavior. So this should be no worse for users with a Phabricator PhD since it's strictly more powerful; we're mostly just making tradeoffs for more casual users. The system would end up a little more complicated but quite a bit more forgiving, so it's conceivable to me that this is a good tradeoff.
I think the concrete steps to implement this are:
- Update the "Members" tab to show why users are members of parent projects more clearly. Currently, when viewing a parent project, this UI shows all members of all subprojects, but does not show why they are members of the parent project. Here's an example:
Instead, this UI should explain that betsy is a member because she is a member of Farm Animals → Dairy Animals → Cows (and possibly one or more other subprojects).
- Possibly, migrate all parent projects to set "Joinable By" to "No One", to retain current behavior. I think this is likely not necessary, but we could consider it, or provide an optional script.
- Allow users to join parent projects, and include parent projects when aggregating the materialized members of a project. I think this stuff is mostly well-defined and has a bunch of test coverage already, so the change is likely not substantial.
- Update the documentation and remove the "Convert" flow.
- Maybe provide a "Move/copy all members to another project..." sort of flow if necessary?