← All notes

May 2026

A social graph without a social graph

Mutual connections, liker identities and comment content kept siloed, public counters only. A centralized visibility middleware as a structural guarantee.

A social product leaks at its edges. The list of who likes, who follows whom, who comments on what forms an exploitable graph. We expose counters, never relationships. The like count is public. The identity of likers is not. The graph exists in the database but is never serialized to the client.

Siloed by default

Mutual connections are visible only to the two parties involved. No endpoint returns a third party’s follower list. Comment content is attached to a thread, not to a queryable profile. You cannot build a person’s activity log by aggregating public views. Minimization is applied at the API response level, not just at display time.

Public counters are enough for social signal. They give traction without handing over the network. An actor who scrapes only gets aggregates, never edges.

A single decision point

Every read goes through one visibility middleware. It takes the caller identity, the requested resource and the relation between them, then decides. No route bypasses this layer. Centralizing the decision is the structural guarantee: you audit one module instead of every controller.

EXIF is stripped at upload, before any storage. Geolocation, device model and timestamp do not survive ingestion. The principle to keep: privacy holds when it is enforced by the architecture, not asked of every developer.