Skip to content

Expand app.certified.graph.* with the rest of the social-graph primitives #210

@s-adamantine

Description

@s-adamantine

Context

Discovered while implementing app.certified.graph.follow in #209. That PR adds only the follow primitive; this issue tracks the additional lexicons a real social graph would need.

The recommendation is to mirror Bluesky's app.bsky.graph.* shape for each, the same way app.certified.graph.follow mirrors app.bsky.graph.follow — so feed-builders and view services that already index Bluesky's graph can index ours with the same logic.

Recommended additions

Proposed NSID Bluesky parallel Why
app.certified.graph.block app.bsky.graph.block Symmetric counterpart to follow — minimum bar for safety/moderation. Same shape: subject: did, createdAt.
app.certified.graph.list + app.certified.graph.listitem app.bsky.graph.list + listitem Curated lists of accounts (mod lists, curate lists, reference lists). Required for starter packs, mute/block lists, feed audiences, etc.
app.certified.graph.listblock app.bsky.graph.listblock Block-by-list — subscribe to someone else's block list. Multiplies moderation reach without per-account block records.
app.certified.graph.starterpack app.bsky.graph.starterpack The natural target for the optional via strongRef on app.certified.graph.follow — wraps a list + a feed-gen ref into a shareable onboarding bundle.
app.certified.graph.verification app.bsky.graph.verification Issuer-signed verified-account claims; complements the existing app.certified.badge.* and app.certified.link.evm identity primitives.

Notes / open questions

  1. subject typing: Bluesky's graph records use a raw format: did string. app.certified already has app.certified.defs#did (used by badge.award); these can either reuse that for in-namespace consistency or stay as raw format: did strings for byte-level parity with bsky. Worth picking one direction up front.
  2. via becomes meaningful once starterpack exists. Today it's a forward-compatibility placeholder (which is exactly what bsky did when they introduced the field).
  3. Mute is intentionally out of scope — Bluesky doesn't ship a mute lexicon either; mutes are AppView-private state, not public graph records.
  4. Don't conflate with org.hypercerts.context.acknowledgement — that's a bidirectional "is this record part of that context?" primitive (e.g. "is my activity in your collection?"), not a social-graph follow. Different question, different indexers.

Suggested sequencing

  1. block (smallest, highest safety value, same shape as follow)
  2. list + listitem (unlocks the rest)
  3. listblock + starterpack (depend on list)
  4. verification (independent — can land any time)

Each can ship as its own PR with the same checklist that #209 followed (lexicon JSON → gen-api → tests → SCHEMAS.md → README + SKILL + ERD updates → changeset).

Discovered-from: #209

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions