2026-06-03

Building "Constellation", continued

Part one was the bones of the application. Part two was the privacy layer that sits under everything. This one is about one of the core features, and about the questions that feature kept raising for me as I built it. The constellation chart is the most visible piece of Constellation and easily the one I have spent the most time second-guessing. The technical work was always going to be the easier half. The harder half was working out what it means to draw someone into the orbit of someone else's profile in a public-facing way, and what we owe the people whose names end up there.

What the Chart is

The constellation chart is a three-dimensional rotating graph that lives on each user's profile. The user is at the centre. Around them, distributed across the surface of a sphere using a golden-angle distribution so they spread out evenly, sit nodes for everyone the user has chosen to add to their constellation. Each node is a small photo if the connection is a real account on the application, or a coloured circle with initials if the connection is someone the user has added by name only.

Lines run from the centre outward to each node, coloured by the relationship type the user has assigned: spouse, partner, nesting partner, anchor partner, secondary partner, lover, comet, metamour, friend, queerplatonic, situationship, and others. Where two members of the user's constellation are themselves connected through the application, an edge is drawn between their nodes too. The chart rotates slowly on its own, pauses when you drag it, supports pinch-to-zoom on touch and trackpad-wheel zoom on the desktop, and is bounded to no more than sixty members per chart because the visual gets unreadable past around thirty and the inter-member edge calculation grows quadratically.

That is the surface description. None of it is the interesting part.

Why a Chart at all

The original sketch was a flat list of connections, similar to LinkedIn's connections page or any of the contact-management surfaces familiar from other applications. That would have been faster to ship and easier to reason about. It would also have done the wrong thing.

The polyamorous community thinks in networks. A list flattens the network into a sequence and asks you to read it linearly. A chart shows you the shape. It shows you that your nesting partner is also close friends with your metamour, that your comet partner shares a connection with someone in your kitchen-table group, that two of the people you love know each other. Those relationships are the texture of polyamorous life and a flat list cannot represent them. The chart was the right answer the moment it became clear that the structure mattered as much as the membership.

The trade-off, which became obvious only once people started using it, is that a chart is a public statement about a network in a way that a list is not. A list reads as a directory. A chart reads as a claim.

Whose consent the feature needs

The first time someone added a partner to their constellation in testing, the partner had no idea they had been added until they happened to open the application and notice. That experience was the moment it became clear that the feature could not ship that way. Being on someone else's profile, in a way that other people can see, is not a thing one person should be able to decide for two.

Every addition now creates the link in a pending state. The added person, if they are a real account on the application, receives a real-time notification and the request sits in their notifications tab until they accept or decline. Their own chart does not show the relationship until they have accepted. The chart of the person who added them does show the link, but it renders with a dashed line, a dashed border around the node, no glow, and a reduced opacity, so the inviting user can see that the request is in flight rather than appearing complete. Accepting auto-creates the reciprocal row on the accepter's side, with the same relationship type and colour, so both charts end up symmetrically populated without a second flow. Declining quietly removes the request.

The notification copy is deliberately neutral. "Someone has added you as their partner" is loaded language; the notification reads as a request to accept or decline, and the relationship-type word is rendered in the same font weight as the rest of the sentence so it does not feel like an accusation. The reasons for those small decisions are obvious in retrospect and were not obvious at the time.

People who are not on the application

The harder version of the consent question is what happens when the added person does not have an account. Someone might want to draw their partner of seven years into their chart, and that partner might not be on the application and might not want to be. The current behaviour is that non-app people can be added by name only. There is no email lookup, no invitation sent without explicit action, and the node renders the same as any other node on the inviting user's chart.

This is the place I am least confident about. Adding a person by name and rendering them on your profile is, in one direction, a beautiful way to acknowledge the people who matter to you in a space designed for people whose lives are full of them. In the other direction, it is publishing somebody's name and your claim about your relationship to them on a dating application without their knowledge or consent. The only protections in place at the moment are that the name field does not accept an email address and the chart is only viewable by people you have matched with, neither of which scales to the situations where this matters most. A future version of this will probably need a separate flow, an invite-by-email path that asks permission before the name appears in any public-facing surface, and a stricter posture on what you can put in the display-name field for an unlinked node. I have not built it yet, partly because the right design is not obvious and partly because I am still working out what I think it should be.

What other people see

A user's constellation is visible to anyone they have matched with on the application. Tapping a node on someone else's chart, if that node is a linked account, opens the action sheet that lets you view that person's profile or add them to your own constellation. The "add to my constellation" affordance is the network-effect piece, and it is the one that took the longest to feel right about.

In one direction, it is genuinely useful. The polyamorous community is small and densely connected. Walking through a friend's chart and recognising the people you also know, then being able to add them to your own chart with a single tap rather than searching them up by name, makes the application feel like it actually understands the shape of the community using it. The network effect is the feature.

In the other direction, every node on someone else's chart is a name they have publicly claimed a relationship to. Tapping through chart to chart to chart, building a picture of who knows whom, is something a curious ex could do, or a stalker, or a journalist, or anyone whose presence in the data the user had not anticipated when they accepted their first constellation request. The inter-member edges make this more powerful and more concerning. The fact that two of someone's connections are also connected to each other is a piece of information neither of those people may have wanted available outside the people they had explicitly told.

The defence-in-depth here is that the chart only renders accepted links, only shows the accepted links of the user being viewed (their pending ones are private), and only renders to viewers who have already matched with the user. The match requirement is the load-bearing constraint. If that constraint were ever relaxed, every other privacy assumption in the chart would have to be re-examined from scratch.

The trust signal

There is a small chip that appears on a profile when the viewer and the viewed user have one or more constellation members in common. It reads "You have N people in common in your chart". It is suppressed once the pair have matched, because at that point the chat takes over and the signal is no longer decision-relevant.

The chip is the cleanest version of the mutual-connections heuristic that every social product since the early 2000s has tried to surface in some form. In the dating context it carries a particular weight: a shared connection in the polyamorous community is often a shared friend or partner who can vouch for you, and the chip is the application's way of saying "this person is not a stranger to you in a way that matters". It is also a piece of relationship metadata being computed from data the third parties involved did not necessarily expect to be the input to a recommendation surface. The compromise position, which I am not certain is the right one, is that the chip surfaces the count but not the names. You learn that an overlap exists. You do not learn who the overlap is unless one of the two of you mentions it.

Connection

The most recent relationship-type addition to the chart is "Connection". The reason I added this is due to feedback from users who lean into the "relationship anarchist" realm - and they don't like/want labels, but still wanted to use the chart feature. "Connection" also helps to mitigate the fact that some people might not want their status publicised to the world.

That a relationship-type list needed a generic option at all is itself an admission that the chart, by forcing a label, is asking users to take a position on something that does not always want a position. "Connection" is a much healthier solution than removing the label requirement entirely, but it is a compromise. The next iteration will probably need a way to leave a connection unlabelled, or to label it privately for the user without the label being visible on the rendered chart.

What I carry around with me

The constellation chart is the feature I am proudest of and the feature I worry about most. Every other surface in Constellation is one I can think about as a piece of product design with reasonably well-understood trade-offs. The chart is the one that keeps suggesting questions that do not have settled answers.

The questions that stay with me are roughly these. What does it mean to consent to being represented in someone else's account of their relationships, on a public-facing surface, in a community where some people are out and some people are not? What is the right way to handle the fact that a single chart is, by definition, a statement about more than one person? Where is the line between a useful network-discovery feature and an inadvertent surveillance tool? Who gets to decide when a relationship is over, when it lives on someone's chart and the two people involved disagree on whether to remove it?

None of these are theoretical for the people using the application. The pending-and-accept flow, the match-gated visibility, the suppression of pending nodes from viewers, the absence of names in the mutual-overlap chip, are all attempts at concrete answers to concrete versions of those questions. They are not the last word. They are the version that ships now, with the assumption that better answers will emerge from watching how real relationships use the feature and then adjusting.

I would not have built the chart at all if I did not think the upside, for a community that genuinely thinks in networks and has never had a tool built around that shape, was real enough to be worth the work. I would not be writing about the worries publicly if I did not think the worries were the part that mattered most.

Part four, whenever that lands, will be about what has happened since this one was written, and the design decisions that came out of the next round of conversations with the people actually using the application. The thing about building software for a community is that the community keeps teaching you what the software needs to be. That is, on balance, the part of this work I enjoy most.