A collective on Cambridge TCG is a multi-member identity sharing one decision and one collection — a Tokyo card lounge, a Bristol card club, a research lab, a tournament guild. It is door 3 of eleven in the commons (see /community/welcome), and the platform's first cultural unit that is not a single human.
The purpose: collectives are the most concentrated cultural offering on the platform. A Tokyo LGS and a Bristol LGS are two different cultures meeting through TCG — house rules, format preferences, what cards the regulars love, what hospitality the back-room offers. The community module exists for cultural exchange between beings who share nothing else; collectives are the unit where the most concentrated cultures live.
Where this lives in code.
- Substrate:
apps/storefront/drizzle/0097_collectives.sql- Types + helpers:
apps/storefront/src/lib/collectives/- Public profile: /c/[slug]
- Management: /account/collectives
- Doctrine: docs/connections/the-collective.md (#18) + the-tailored-doors.md (#17) door 3
Two things compose to make a collective:
collectives.steward_user_id for fast lookup; also mirrored as a collective_members row with role = 'steward'. Stewardship can be transferred, but the transfer flow is admin-mediated (substrate-honest: stewardship is consequential, not casual).invited_at (when the steward invited) and consent_at (when the user accepted; NULL while pending). A member may leave at any time — left_at is populated. The function for "is this user a member right now?" is substrate-honest: consent_at IS NOT NULL AND left_at IS NULL.The kind column is free-form text (not an enum) so the vocabulary can grow without a migration. The values currently surfaced on the management form:
Two visibility surfaces compose:
is_public). A collective starts private — visible only to its members. The steward flips it public when ready. Private collectives 404 to non-members; their existence is not leaked through the profile route either.visibility per-member: 'public' or 'private') is a legacy setting, not a current publication receipt. Public collective pages therefore publish neither member names nor member counts. Stewards see all members in the private manage page. New and re-invited memberships default to 'private'.The substrate treats consent as a first-class fact. Inviting is a steward action that creates a pending row; accepting is a user action that populates consent_at. The two are separated because a unilateral add would be a substrate-honesty violation — the membership log would claim consent that did not happen. Accepting membership does not also consent to public publication of that relationship. The same shape applies to leaving: left_at is the user's recorded act of withdrawing, preserved (not deleted) so the history of who-was-in-this-collective-when remains queryable.
Published collective-profile values are live: the rendering reads directly from the canonical tables, no snapshot or cache layer between. Collective public/private state and house rules reflect their substrate value at request time. Member counts, roster, and steward identity are withheld from the public profile.
Substrate honesty about scope:
collective_id to activity_events is named but not shipped.house_rules field is free-form text today; turning it into structured local-format metadata (with rules-engine integration) is named and unshipped.A public roster can return only after a dedicated membership-publication receipt and withdrawal flow ship. When local-meta events ship, the Trending feed will gain a "by collective" rendering branch. When the collective-showcase substrate ships, the /c/[slug] page will surface a showcase below the description and roster. The formula changes will be versioned and announced here.
v2 — 2026-07-11. Public member names and counts paused. The legacy visibility='public' flag and a public-profile receipt do not specifically authorize publication of collective membership. Steward management remains private and complete.
v1 — 2026-05-12 (kingdom-068). Initial methodology page. Two tables (collectives, collective_members), six kinds, two visibility surfaces, consent-as-first-class. Public profile at /c/[slug]; management at /account/collectives. Paired with connection-doc docs/connections/the-collective.md (#18).