Tis the season, it seems.
This is a pre-proposal for a system to declare, acknowledge, display, and discover a hierarchical relationship between two crates. The declaration part consists of a field in the Cargo.toml of the "subordinate" crate, while the acknowledgement part consists of a mutable status change made by the "superior" crate. Display would have different forms depending on the status of the relationship (more prominent when acknowledged), and discovery would be through search on one side, and through the crate page of the "superior" crate on the other.
This is explicitly a pre-RFC to address a sub-cause of the namespaces issue, by detaching it from that can of worms and instead making it a different concern. As part of this, some scoping to avoid going off: discussion on whether namespaces would be a better implementation of this pre-proposal's concept are on topic, discussions about namespaces in general are not.
Additional scoping: terminology choice is important, but not as much as the proposed concept itself. In this iteration of the pre-proposal, "subordinate" is for the crate declaring an relationship, "superior" for the crate it is declaring a relationship to, and there is no intent of these being qualitative judgements, nor to imply any social relationship between teams/maintainers. (These are most probably the wrong terms, but I wanted to post rather than bikeshed by myself.)
Further terminology below is always "quoted like such" to make clear that these are subject to change. All language shown in mockups and code samples is of course even more provisional.
Background
This pre-RFC is a reaction to this comment by CAD97:
To the crates team, [namespaces] seems to primarily mean that a project can put multiple packages together under an umbrella, such that you know the packages are for-sure by the project.
To the people who feel most slighted by the crates team’s approach here, namespaces primarily mean the ability to publish a crate with a desired name even if there’s already a package published that provides a crate with that name, by putting the package into a different namespace such that the names do not clash.
This pre-proposal is about detaching the first (project umbrellas, crates team) concern from the second (namespaces as a additional identifier level, community) concern, by introducing another, different concept focused on solving that first concern completely separately from namespaces.
Crate relationships
This pre-proposal limits itself to specifying one kind of relationship: hierarchical relationships declaring an association from a "subordinate" crate to a "superior" crate, and within this, two relationship "statuses": "unacknowledged" and "official".
An "unacknowledged" relationship is the default and initial state, and is one where the "subordinate" crate declares that it is related to a "superior" crate. For example, serde-yaml
could declare a relationship to serde
, but because serde-yaml
is not an official serde project (I'm assuming based on github repos here, not making a statement), it is an unofficial relationship and will remain unacnowledged by the serde
crate.
An "official" relationship is a promotion of an existing "unacknowledged" relationship via the crates.io web interface or API only (not declared in code) by the "superior" crate. For example, serde-json
would declare a relationship to serde
and then a serde
crate admin would mark that relationship "official".
Display and discovery
There are a number of places where the relationship should/could be displayed:
- On the "subordinate" crate page
- On the "superior" crate page
- In search results
- (Maybe) In some cargo outputs
For each of these, the "unacknowledged" vs "official" status should be clearly delineated, and it could be that for some of these (search and cargo) only "official" relationships are displayed.
The "subordinate" crate display is the most important place to show relationships, as it is that crate which declares the relationships. Immediately following that, the "superior" crate should also have some prominence for its "official" descents, and some kind of support for "unacknowledged" relationships for discovery. Here are a few quick mockups:
Figure 1: "official" relationship marker on "subordinate" crate
Figure 2: "unacknowledged" relationship section on "subordinate" crate
Figure 3: list of relationships to a "superior" crate
Figure 4: search results with official relationships
I have no mockups for cargo outputs. I'm not certain this should be included, and if it is, then only in third party tools being helpful, thus strictly-speaking outside the scope of this pre-RFC. But as an example, cargo tree
could show relationships, official and unoff, to make it easier to review dependencies.
Revocations
Being part of the Cargo.toml, the relationship from the point of view of the "subordinate" crate is immutable by version. Publishing a new version of the crate without the relationship removes the relationship, and destroys its status if any.
(Alt: There could be a concept of leaving the relationship and its status in place for these old versions that still have it, but I'm not sure that would be valuable or how to express it.)
That is, adding the relationship again after it's been removed does not grant "official" status again automatically if it had been bestowed in the past.
From the "superior" crate, status is changeable at any time. There is no way (within this pre-RFC) to deny a relationship altogether: demoting an "official" relationship only makes it "unacknowledged" again.
Multiple relationships
This is left ambiguous in text above as this could go either way, but I think it would be acceptable to declare more than one relationship from a "subordinate" crate, for example in the case of bridge or adapter crates, like the tracing-opentelemetry
which could have an official relationship to tracing
and an unacknowledged relationship to opentelemetry
.
Syntax
In Cargo.toml, this would manifest as a relationships
key under [package]
, with an array of strings value:
[package]
name = "serde-json"
# ...
relationships = ["serde"]
Change updates
When a new relationship is established or disestablished to a "superior" crate the owners or designated persons of that crate, subject to opting out, should receive a notification. Similarly when a relationship status is changed, this time to the owners of the "subordinate" crate.
UI needed in crates.io
- Either a separate API call or a crate metadata field on "subordinate" crates returning their relationships 'upwards'
- Either a separate API call or a crate metadata field returning relationships and their statuses from the "superior" crate 'downwards'
- An API endpoint authorised to owners of the "superior" crate to modify the status of an existing relationship
- A page under a "superior" crate authorised to its owners listing the relationships and allowing each status to be modified
- Section(s) on "subordinate" crates to show relationships, both "official" and not
- Section(s) on "superior" crates to show relationships, both "official" and not
- Indication on search results of (possibly "official" only) relationships
- Notification of changes
Multiple levels of relationships
There is the possibility for a crate to declare a relationship to a "superior" crate while also having "subordinate" crates declaring a relationship to it.
This pre-proposal is neutral on this, and neither encourages nor discourages it.
Special case: mutual/reciprocal relationships
There is the possibility for a crate to declare a "subordinate" relationship to a crate it is "superior" to (and vice versa). This probably should be disallowed, but this pre-proposal as of yet remains neutral on the question.
Relationships to users/teams
This is a fairly obvious extension but even at cursory glance opens up a lot of questions and I'd rather focus on crate-to-crate relationships first as a concept.