Research: customer-member onboarding prior art and body facts (customers-get-voting-power-onboarding-owed)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-30 19:09:05 +01:00
commit 6cf24644bc
2 changed files with 161 additions and 0 deletions

View file

@ -0,0 +1,105 @@
# Customer onboarding: body facts at 2026-10-30
Served: the same forks. Eyes pass over Bifrost origin/main, Heimdall, StreamPixels state/map.yaml, gamecult-ops inventory and the eureka mind. Facts only.
# Eyes: customer onboarding, what the body can do today (2026-10-30)
Read via `git show origin/main:` after `git fetch` in each repo. Bifrost origin/main = cc76f0f; Heimdall = 5146c72; StreamPixels = 9a113d3; gamecult-ops = c03e03c. Facts only. Not read: Bifrost tests, live DB contents, jurisdiction-map.md, bifrost-mvp-plan.md body, Heimdall implementation (src/app.ts), StreamPixels docs/joystick-integration-map.md, Yggdrasil live state (no ssh).
## 0. The trigger (mind)
- `eureka-body:ruling:customers-get-voting-power-onboarding-owed` (Operator, 2026-10-30, InForce). Quote: "Funny coincidence, then, that our first customer, and likely the largest for a while, is a fox themed vtuber, with 1,500€ of work contracted, and therefore voting power. We need a workflow to onboard customers on our platform since we're giving them voting power". Ruling text: "Prior-art and body passes come first; estate placement, weighting and related-party handling are forks for the operator." `precedents: []`.
## 1. Bifrost (F:\Projects\Bifrost; ASP.NET Core 8 Razor Pages, PostgreSQL/EF Core)
### 1a. Member and identity model (code at origin/main)
- `UserAccount` (src/Bifrost.Web/Domain/BifrostModels.cs ~l.213): Id (Guid; per docs/context.md "UserAccount.Id is the subject" of the OIDC issuer), BifrostIdentity, optional GitHubUserId/GitHubLogin, HeimdallAccountId, DisplayName, AvatarUrl; 1:1 `MemberProfile` (nickname, headline, portfolio, skills, availability, notes) and 1:1 `Membership`.
- `Membership` (l.~330): `MembershipStatus` Authenticated | PendingApproval | Active | Suspended (l.5-10); flags IsPlatformAdmin, CanManageProjects, CanManageLedger, CanModerateMotions; `RoleAssignment` roles StandardMember | Producer | Maintainer | LedgerReviewer | PlatformAdmin; `TierSnapshot` (Kind Patron|Contributor, Label, Weight, IsCurrent).
- Stored in PostgreSQL via EF migrations (Data/Migrations, 15 migrations 2026-04 to 2026-10-22). Not CultCache. CultCache is used only for the bridge/receipt/governance-thread/persona-feedback stores (`.bifrost/*.cc`; README, docs/bridge.md).
- Sign-in paths (Program.cs): GET `/auth/sign-in` (GitHub OAuth, l.314); POST `/auth/bifrost/register` anonymous (l.342) takes `identity`, optional displayName, returnUrl; signs in as Authenticated, no password/credential visible in the handler (BifrostIdentityService.RegisterNativeAsync, Features/Membership/BifrostIdentityService.cs:15); GET `/auth/heimdall/{provider}` (l.374) with AllowedProviders discord, patreon (HeimdallAuthService.cs:37-40); Heimdall complete page l.530-537.
### 1b. Estates
- No "estate" concept exists in Bifrost code. `git grep -w estate(s)` in src/ and README returns nothing; hits are only in docs/research/2026-10-29-estate-tally-game-theory/ (research, with Python sims) and the swarm-governance research note. Minds / Members / Users / Patrons blocks exist only as rulings (section 5).
- Closest code analogues: `MembershipStatus` (Authenticated ~ Users, Active ~ Members), `TierSnapshotKind.Patron`. No Persona/Mind account class; `BridgeActorKind` Member|Agent|Persona|Service (BifrostModels.cs:178) is for bridge actions only (research note Part 1).
### 1c. How a person joins today
- Invite-only alpha (README "Alpha Scope"). `MembershipInvitation` (BifrostModels.cs:406) keyed on normalized GitHub login (MembershipSynchronizationService.cs: invitation lookup by NormalizedGitHubLogin). Admin invites at Pages/App/Members `OnPostInviteAsync` (Index.cshtml.cs:34); invited GitHub sign-in becomes PendingApproval; admin `OnPostApproveAsync` (l.92) sets Active, ApprovedAtUtc, StandardMember role. Also OnPostToggleRoleAsync (l.127), OnPostSetTierAsync (l.184), OnPostUpdateProfileAsync (l.240).
- Un-invited GitHub or native sign-in stays Authenticated. Bootstrap admins by GitHub login via `Bootstrap:AdminGitHubLogins` become Active admin automatically.
- Heimdall path: Discord role (KTLST guild role) or Patreon tier title (`Inner Sanctum`) entitlement grants Active (HeimdallAuthService.cs ~l.296-324; docs/app-profiles/bifrost.md in Heimdall).
- /App is ActiveMember-gated (Program.cs:57 per research note).
- No application form, no customer/client type, no contract record, no related-party flag, no email invite (invitations are GitHub-login keyed), no self-service for a person without GitHub, Discord-guild role, or Patreon tier.
### 1d. Vote weighting in code (not the ruled design)
- `Membership.EffectiveVotingWeight` = 0 unless Active, else `Math.Max(1, sum of current TierSnapshot weights)` (BifrostModels.cs:357-361).
- Patron tiers (Features/Patronage/PatronTierPolicy.cs): Bronze 10 pts w1, Silver 100 w2, Gold 1,000 w3, Platinum 10,000 w4, Unobtanium 100,000 w5. Points from `PatronSupportEvent` amounts; one-time donations: full for 30 days, then 50% decayed 1%/week; recurring snapshots count while current; adjustments added (GetHistoricalDonationPoints). `PatronSupportEvent` carries ProjectId, provider (Manual|Patreon|PayPal|Stripe), currency code, amount.
- Contributor points: `PointTransaction` (BifrostModels.cs:773; types ManualAdjustment, ApprovedWork, ContinuousRoleCredit, PatronSupport, Decay). Contribution-to-vote scaling: no code found that scales vote weight by contribution beyond TierSnapshot kind Contributor set by admin (OnPostSetTierAsync).
- No log or exponent curve anywhere in src (grep Math.Log/Sqrt empty). Rulings `governance-vote-power-scaling` (log patrons, lower exponent members) are not implemented.
### 1e. Motions, brake, timelock (code)
- `Motion`/`Vote` Postgres rows (BifrostModels.cs:665, 702). MotionGovernanceService.cs: CreateMotionAsync (:13), CastVoteAsync (:47; weight copied from actor at cast time), CloseMotionAsync (:95; manual, by creator or CanModerateMotions). Pass = For/(For+Against) >= ApprovalThreshold, abstain excluded; no quorum.
- Thresholds (MotionCategoryPolicy.cs; research note): Bugs .15, Cosmetics .30, Balance .40, Features .50, NewContent .50, FundamentalDesign .66.
- Brake and timelock: absent. `git grep -i -E 'timelock|brake|quorum'` in src/ returns nothing. They exist only as rulings. `motion.create/vote/close` command names appear in MotionEveSurfaceService with no handler (research note Part 1). Only machine surface: GET `/eve/governance/surface` (Program.cs:513), deprecated Eve JSON. Motions are not typed CultMesh state.
- Docs: docs/verse-service-contract.md lists schema `gamecult.bifrost.governance`; motion/vote schema ids marked todo (:256 per research note).
### 1f. Other Bifrost surfaces relevant to a customer
- Stripe: `StripeOptions` (Configuration/StripeOptions.cs; EnableCheckout, SecretKey, WebhookSecret, GeneralPatronageGitHubLogin, Success/Cancel URLs default to velvet.gamecult.org); routes GET `/patronage/{project}/checkout` (Program.cs:431) and POST `/patronage/stripe/webhook` (:489); Webhook records a `PatronSupportEvent` against the configured GeneralPatronageGitHubLogin account.
- PayPal/Patreon: docs/paypal-patronage.md: Heimdall POSTs HMAC-signed support facts to `/heimdall/patron-support/events` (Program.cs:408). "PayPal owns money movement... Bifrost owns patronage meaning".
- Ledger (`LedgerEntry` types PatronCredit, ContributionCredit, NominalCompensation, Adjustment; payout proposal batches). README: "no real payout execution in v1"; "internal ledgers only".
- OIDC issuer for Matrix chat (docs/oidc-issuer.md; main 1894f65/83daabe): Bifrost is the identity issuer; back-channel logout reconciler ends sessions of non-Active subjects (OidcLogoutReconciler). Remaining scar: Heimdall still mints its own account id.
- Concept Mill votes (ConceptVotes/*, VoterClass Anonymous|Account|Member): per-subject appraisals, not motions.
### 1g. Documented gaps
- Swarm research note (docs/research/2026-10-29-swarm-governance-prior-art.md Part 1) and follow-up `eureka-body:follow_up:swarm-governance-on-bifrost` item text: no quorum; manual close only; Personas cannot be Active members or vote; motions/votes are Postgres rows not typed CultMesh state; only machine surface is deprecated Eve JSON; motion.* commands without handler; no Matrix surface; Yggdrasil behind main.
- README "Next Build Target" and docs/full-implementation-strategy.md l.11: "not an internet-facing alpha"; payout proposals, revenue-share automation, decay automation, GitHub App guidance are future. No single "gaps list" file found.
## 2. Heimdall (F:\Projects\Heimdall; TypeScript/Fastify; in-memory + Postgres stores)
- Providers (src/contracts.ts:1): discord, patreon, github, twitch, youtube, spotify, joystick.
- App profiles (src/app-profiles.ts): repixelizer (identity discord, patreon); streampixels (identity twitch, youtube; managed connection twitch, youtube, joystick; allowedReturnOrigins streampixels.gamecult.org); bifrost (identity+entitlement discord, patreon; l.138-143); ghostlight (discord). Built-in app slugs are "seed data, not the set of permissible apps" (contracts.ts comment).
- Bifrost integration (docs/app-profiles/bifrost.md): Bifrost starts Discord or Patreon OAuth with a server-owned entitlement policy over `backend_callback`; Heimdall delivers to `https://bifrost.gamecult.org/auth/heimdall/callback`; Bifrost creates/updates UserAccount, activates standard membership, issues its own cookie. Patron sync: POST `/v1/apps/bifrost/patron-support/sync` -> signed RecurringSupportSnapshot to Bifrost. Heimdall does not own ledgers, points, votes.
- Bifrost's own AllowedProviders is discord, patreon only (HeimdallAuthService.cs:37-40). Twitch/YouTube are not Bifrost sign-in providers; Heimdall's bifrost profile does not list them. GitHub is signed in by Bifrost directly, not through Heimdall.
- Non-technical external person today: could sign into Bifrost with a Discord account holding the KTLST role in the GameCult guild (Active at once), or a Patreon account with an active `Inner Sanctum` tier (Active at once), or GitHub if invited by login, or native register (identity string, lands Authenticated, no vote). No email/password/magic-link sign-in exists in Heimdall's provider list. Whether the live Heimdall has Discord/Patreon creds configured: runbooks/heimdall-discord-launch.md and bifrost-alpha-deploy.md say configured (inventory.md:1019 "Heimdall-mediated Discord/Patreon access and Patreon support intake env are configured"); live check not done.
- Heimdall state map (state/map.yaml l.62-63, 129-130): live release d51fa6b (hand-deployed 2026-10-19) includes Joystick H1; remaining: human canaries, refresh/revocation, admin surfaces.
- Joystick consent work (open): `joystick:follow_up:h1-joystick-consent-round-trip` (the streamer completes a Joystick connect consent through a creator-bound streampixels connect start on live Heimdall d51fa6b; verify a joystick linked identity keyed by channel_id). StreamPixels map.yaml open_operator_decisions: "Joystick S0/S1: the streamer's consent click is still owed before the connector goes live". Joystick is a managed creator connection only, not a viewer sign-in (docs/app-profiles/streampixels.md; `joystick:ruling:signin-waits-for-public-bot`). Other Joystick follow-ups in docs/architecture.md:442-457: cross-process-failed-refresh-marker, connect-start-needs-app-auth, heimdall-idunn-onboarding, joystick-viewer-signin-public-bot.
- Open High finding relevant to identity linking: `gamecult-chat:follow_up:streampixels-link-target-takeover` (InForce): an unauthenticated Heimdall link start for streampixels can name any profile id; StreamPixels redeem links with no session check; Plausible High, unconfirmed.
## 3. StreamPixels (F:\Projects\StreamPixels, state/map.yaml, state/evidence.jsonl)
- Engagement (map.yaml l.17-70): the StreamPixels client; `budget_eur: 1500`; split even, EUR 500 per milestone (operator 2026-09-14; currency corrected from USD by operator 2026-10-25); milestones M1 "whole system running end to end on her stream" (September), M2 committed 2026-09-15: GPU fixed-capacity particle pool and AquaSynth impact audio (October), M3 TBD sold by proposal (November). Cadence: "The operator needs one milestone paid per month to survive." evidence.jsonl l.16 records the engagement (written as "$1,500" on 2026-09-14).
- Recorded money status: map.yaml has no field recording a milestone as invoiced or paid; no invoice/payment/received hits in map.yaml or evidence.jsonl (grep). Milestone completion state: M1 still in progress per `focus: milestone-1-unity-repair` and active_subgoals (A3b, C1 remaining, l.153); the map.yaml read ended before the full active_subgoals/next_action sections.
- Consent: map.yaml `consent`: "Her channel is not a marketing asset. Publicly associating her with the overlay requires asking her."
- Business context l.60-66: "She has explicitly ruled out microtransactions".
- Heimdall/Bifrost identity for the client: no Bifrost or Heimdall account, user id or invitation naming the client or her streamer handle found. Searched Bifrost and Heimdall for the client's and streamer's handles: no account or invitation found. Her Heimdall identity, if any, lives in live DB (not checked). StreamPixels has creator memberships and linked identities in its own store (apps/service/src/app.ts ~l.698, 1491-1602) via Twitch/YouTube/Joystick; live contents not checked.
- StreamPixels forks stay in chat, no Kiko desk: `web-customize:ruling:sp-forks-in-chat-until-thing2` (2026-10-26).
## 4. Payment / invoicing / money received
- Recorded payment-receiving surfaces: Bifrost Stripe checkout+webhook (patronage; runbooks/bifrost-alpha-deploy.md:84-98 lists `Stripe__EnableCheckout`, `Stripe__SecretKey`, `Stripe__WebhookSecret`, `Stripe__GeneralPatronageGitHubLogin`; whether live-enabled unknown, inventory.md has no Stripe flag); Heimdall-signed Patreon and PayPal support facts (docs/paypal-patronage.md); StreamPixels donation source Ko-fi webhook (map.yaml settled decision, for streamer donations, not for the operator's fees).
- No invoicing surface found: grep of gamecult-ops (excluding repo-census docs) for invoice returns nothing; Bifrost has no invoice entity (LedgerEntry/Payout are internal, "no real payout execution", "internal ledgers only"). `PatronSupportEvent` is the nearest "money received" record (amount, currency, provider, externalSupportId, ProjectId) and drives patron voting points; there is no contract/engagement/client-payment event kind (kinds: OneTimeDonation, RecurringSupportSnapshot, SupportAdjustment; providers Manual, Patreon, PayPal, Stripe). A Manual provider event can be admin-entered.
- Treasury: `eureka-body:follow_up:swarm-treasury-and-revenue` (InForce): typed runway document (balance, committed costs, expected income) "The operator enters figures; no bank credentials are ever handled by agents"; not built. Owner repo GameCult/gamecult-ops. Source ruling `eureka-body:ruling:operator-legal-vehicle-shared-solvency` (operator is GameCult's legal and financial vehicle; her bank account pays for server and tokens).
- Operator's bank/payment record for the EUR 1,500: not recorded in any file read.
## 5. The mind (ids)
Follow-ups (all InForce, campaign eureka-body):
- `eureka-body:follow_up:swarm-governance-on-bifrost` (admitted 2026-10-29T20:45Z).
- `eureka-body:follow_up:co-op-charter` (2026-10-29T21:13Z): one typed charter document in Bifrost with every governed parameter (estates and weights, within-estate curves and exponents, operator influence cap, bloc position rule, quorum, category thresholds, close timing, decision delay and cancel); amended by motion, higher threshold for charter amendments (Debian 3:1 cited). Gathers rulings governance-estate-blocks, governance-vote-power-scaling, estate-weights-normalize-by-turnout, swarm-decides-without-operator, operator-influence-below-half, swarm-governance-in-bifrost, desk questions 37, 38, 40, 41. Not on bring-up path; operator holds the seat until Bifrost governance is live.
- `eureka-body:follow_up:swarm-treasury-and-revenue` (2026-10-29T21:24Z): treasury runway doc plus a revenue-map Eyes pass.
Rulings (Operator, InForce):
- `eureka-body:ruling:governance-estate-blocks` (10-29): four blocks Minds (Personas), Members (Active members), Users (authenticated accounts), Patrons (patron tiers); each block's internal vote gives its position; block weights are governed settings changed by motion. The ruling lists no Customers estate.
- `eureka-body:ruling:estate-every-estate-equal-seed` (10-29, answers `estate-overlap-and-seed`): a person votes in every estate they belong to; estates start at equal weight.
- `eureka-body:ruling:estate-bloc-parliament-at-threshold` (answers `estate-bloc-position`): each estate casts whole weight For only if its internal For share meets the category threshold; known cost: low categories rescaled before go-live (0.15 passes on 3.7% overall support).
- `eureka-body:ruling:estate-weights-normalize-by-turnout` (10-29): only estates where someone voted count; weights renormalized to sum 1; empty estate drops out.
- `eureka-body:ruling:governance-vote-power-scaling` (10-29): patrons by strongly flattened log of donation total; members by contribution with a lower exponent; curves and exponents governed; exact functions "a sketch to be calibrated by simulation (her numbers are feel, not gates)"; replaces `max(1, tier weight)` when the governance cut lands.
- `eureka-body:ruling:operator-influence-below-half` (10-29; supersedes `operator-influence-capped-at-half`): strictly less than half; mechanism and number from simulation; a governed parameter. Research: Bifrost docs/research/2026-10-29-estate-tally-game-theory (18bbe6c adds bloc-parliament-at-threshold and operator influence cap; present case Members = her alone, Minds 8, Users/Patrons empty, README l.84).
- `eureka-body:ruling:swarm-decides-without-operator` (10-29): no quorum rule may require her vote; rules out at-least-two-estates floor.
- `eureka-body:ruling:motion-deadline-quorum-autoclose` (10-29, answers `motion-quorum-and-close`): default 72h window; Bifrost auto-closes; quorum is a majority of eligible voters.
- `eureka-body:ruling:brake-to-bifrost` (10-29; quote: "hand the brake to bifrost") and `eureka-body:ruling:brake-anyone-pulls-motion-releases` (answers `brake-engage-release`): any Mind or human member engages the brake at once, every pull published with reason; releasing takes a motion (short window, e.g. 24h, majority); until Bifrost governance is live the brake stays in the root-owned swarm control store (`eureka-body:ruling:brake-dial-root-store-now`, 2026-10-02).
- `eureka-body:ruling:decision-timelock-owner-applies` (answers `decision-applies-how`): passed motion published as typed CultMesh state with an effective time (e.g. 24h); the owning service applies it then; cancellable until then; who may cancel follows brake-to-bifrost and the charter (operator holds no private cancel).
- `eureka-body:ruling:swarm-governance-in-bifrost` (2026-10-10); `swarm-shares-log-bound`; `swarm-membership-operator-rules` (operator rules births/retirements/transfers; any mind proposes; a mind may leave).
- `eureka-body:ruling:operator-legal-vehicle-shared-solvency` (10-29); `eureka-body:ruling:customers-get-voting-power-onboarding-owed` (10-30).
- Withdrawn question `eureka-body:question:persona-vote-weight` (replaced by estate blocks); withdrawn `estate-internal-tally` (restated as `estate-bloc-position`).
- "Kiko rulings": the 2026-10-29T21:41:40Z batch (ordinal 4430) answering desk questions: estate-overlap-and-seed, estate-bloc-position, brake-engage-release, decision-applies-how, motion-quorum-and-close. No separate document labeled Kiko beyond these and `web-customize:ruling:sp-forks-in-chat-until-thing2`.
- No ruling or follow-up found on: a Customers estate, related-party/conflict-of-interest handling for a customer who is a related party, customer vote weight from contract value, a customer onboarding workflow (other than the 10-30 ruling), or a co-op charter document existing yet (semantic query top hits showed none).
- Joystick: `joystick:campaign:self`, `joystick:follow_up:h1-joystick-consent-round-trip`.
## 6. What Yggdrasil runs for Bifrost
- gamecult-ops inventory.md:1021: live release `/srv/bifrost/app/releases/20261010043032-67072b2`, revision `67072b28923017f93f484d901c7a6d31e3678d88`, deployed 2026-10-10; app user `bifrost`, root `/srv/bifrost/app`, env `/srv/bifrost/env`, bound `127.0.0.1:5080` via `bifrost.service` behind nginx (`bifrost.gamecult.org`, TLS issued 2026-06-10), local PostgreSQL 16. Heimdall-mediated Discord/Patreon access and Patreon intake env configured (l.1019).
- Distance: `git rev-list --count 67072b2..origin/main` = 94 today (follow-up text says 89 at 2026-10-29). Commits since 67072b2 touching src/: OIDC issuer for Matrix chat (83daabe, 404dafd), Heimdall sign-in cookie ring and signed callback (15f96c4, b7e3bdf, b2110f5), Mill votes sign-in offer (cf74019), NuGet pins/lockfiles, mouth-all-personas (cc76f0f, tools/). So OIDC issuer and the newest Heimdall sign-in hardening are not live.
- Also on Yggdrasil from Bifrost: `bifrost-persona-feedback.service`, `bifrost-persona-mouth.service`, `bifrost-watchdog-notice` timer (inventory.md:710-729; Persona delivery via Discord per that inventory text; main now moves Persona speech to Matrix per docs/bridge.md:199). Whether the Stripe/Heimdall env flags are live was not verified (no ssh).
- Deployment authority is Idunn for managed workloads; Bifrost deploy is by `scripts/deploy-bifrost-alpha.sh` / runbooks/bifrost-alpha-deploy.md per inventory (interim); not confirmed which path produced 67072b2.

View file

@ -0,0 +1,56 @@
# Customer-member onboarding: prior art
Served: eureka-body:ruling:customers-get-voting-power-onboarding-owed (2026-10-30), the forks on customer estate, weight, decay, related parties and join flow. Eyes pass, facts only; [U] marks unverified.
# Eyes facts: customer onboarding and voice in multi-stakeholder / platform co-ops (2026-10-30)
Method: web search result summaries plus two WebFetch attempts. Most facts come from search-result summaries, not full-page reads. "[V]" means the source was returned by search and the claim is stated there; "[U]" means unverified, conflicting, or not found. No primary statutory text was retrieved (both wetten.overheid.nl fetches returned only tables of contents / metadata).
## Q1. Admission and classes in multi-stakeholder and platform co-ops
- Stocksy United [V]: three classes. A = advisors on board, capped at 5, may buy up to 200 shares (one support page). B = staff, may buy one extra B share a year. C = contributing artists, max one $1 share. Class C cap of 1,000 was removed by member resolution (support docs date it 2018). Patronage for A and C is not tied to share count. Members can submit resolutions. Sources: https://stocksy.com/legal/rules ; https://support.stocksy.com/hc/en-us/articles/201658696 ; https://support.stocksy.com/hc/en-us/articles/201659716-Is-there-a-limit-on-the-number-of-Co-op-members ; https://geo.coop/content/stocksy-united-removes-its-membership-cap ; https://support.stocksy.com/hc/en-us/articles/201808247-Can-members-purchase-more-shares-in-the-Co-op
- Stocksy: the 1,000 cap led to regular review and removal of inactive members (company announcement via https://gdusa.com/stocksy-member-owners-open-door-to-new-contributors/) [V, secondary].
- Fairbnb [V, partly planned]: intends to admit hosts, guests, local businesses, neighbours; per a 2020-era description workers and advisors are members, local partners/users/hosts "in the foreseeable future"; funders' voting power is statutorily limited to one third of assembly votes. Another source says it currently operates as a worker co-op without hosts. Italian and Spanish co-op law reportedly makes multi-stakeholder creation from scratch hard. Sources: https://www.thenews.coop/can-fairbnb-become-a-platform-for-community-powered-tourism/ ; https://wiki.p2pfoundation.net/FairBnB . Current composition [U]; one source is a promotional travel blog.
- Resonate [V, one interview, other figures conflict]: three voting classes, Music-Makers 45%, Fans 35%, Collaborators 20% (Peter Harris interview), plus a Founder class with early board-appointment say. Listener membership 5 EUR/yr (Billboard). Source: https://www.resilience.org/stories/2018-06-15/resonation-an-interview-with-peter-harris/ ; https://geo.coop/content/own-music-you-stream-resonate . Whether percentages are voting or profit share is conflated across sources [U]; check resonate.is.
- Eva (Montreal) [V, self-reported]: three categories, driver members, rider members, worker members. Fees and requirements not found. Sources: https://en.wikipedia.org/wiki/Eva_(coop%C3%A9rative) ; https://wiki.p2pfoundation.net/Eva_Coop . Up & Go: described as worker-owned cleaners' co-op in NYC; no membership-class details found [U].
- Open Food Network [V]: governance as collective of affiliates under a "global pledge"; Open Food Foundation oversees governance and finance; UK arm "co-op of co-ops" with food hubs, farmers, shoppers as members, sociocratic circles. Sources: https://www.openfoodnetwork.org/about-us/ ; https://www.uk.coop/blog/open-food-network-making-food-systems-fair-and-sustainable-unfound . No customer admission steps found [U].
- Eroski/Mondragon [V]: worker-members and consumer-members; General Assembly of 500 delegates, 250 worker and 250 consumer; 1.3M+ consumer members (2022). Surplus: 40% to worker-members, 50% reserves, 10% COFIP (2026 assembly). Consumer-member fee (~$75/yr) from older source [U]; per-member consumer vote weight not found [U]. Sources: https://corporativo.eroski.es/wp-content/uploads/20260528_PR_General-Assembly-2026.pdf ; https://archive.grocer.coop/node/7142 ; https://eurocoop.coop/news/184-Eroskis-growing-membership-putting-members-at-the-heart-of-co-op.html
- REI [V, secondary]: lifetime membership $30 one-time (older $15/$20); dividend now "Co-op Member Reward" (patronage dividend and/or promotional reward, decided annually); historically ~10% of regular-price spend; ballot for board election sent with dividend notice. Older rule: active member = paid fee and bought >= $10 in a calendar year [U for current]. Sources: https://www.rei.com/membership ; https://www.rei.com/membership/join ; https://www.nbcnews.com/select/amp/rcna172651
- Quebec solidarity co-ops [V]: classes user members, worker members, supporting members (1997 amendment). Required share count may differ by class; rebates to users by business done, to workers by work volume; supporting members get no rebate. Voting formula not found; set in by-laws [U]. Sources: https://www.publicationsduquebec.gouv.qc.ca/fileadmin/Fichiers_client/lois_et_reglements/LoisAnnuelles/en/1997/1997C17A.PDF ; https://cdn-contenu.quebec.ca/cdn-contenu/adm/min/economie/contenu/cooperatives/modeles_reglement/MO_reglements_generaux_solidarite.pdf (model by-laws, not opened) ; https://www.co-oplaw.org/?p=8947
- Italian social co-ops, Law 381/1991 [V]: volunteer members (soci volontari) unpaid, capped at 50% of membership (art. 2); user members (soci fruitori) are service beneficiaries or relatives, reimbursed documented expenses only; investor members (soci sovventori) permitted; type B requires >= 30% disadvantaged workers, who should become members where possible. Voting caps for sovventori not retrieved; civil code art. 2526 not read [U]. Sources: https://www.bosettiegatti.eu/info/norme/statali/1991_0381.htm ; https://base.socioeco.org/docs/l_381_91.pdf ; https://www.fpcu.it/App_Common/Files/FilesEventi/346348/Slide%20videoconferenza%2014_12_2018.pdf
- Platform Cooperativism Consortium / Exit to Community [V, thin]: E2C (Schneider, Mannan; "Exit to Community: Strategies for Multi-Stakeholder Ownership in the Platform Economy") describes transfer of ownership to users, workers, stakeholders. No findings on customer admission mechanics [U]. Source: https://wiki.p2pfoundation.net/Nathan_Schneider_on_Exit_to_Community_and_Community_Ownership_Through_Platform_Coops
- Not found: Fairbnb/Resonate/Eva application-and-approval steps and member agreement text [U].
## Q2. Purchase-based voice, plutocracy, dominant customer, related parties
- Ag co-ops (US) [V, 1990s-2003 sources]: 93% of direct-membership co-ops used one-member-one-vote, 7% proportional (patronage-based extra votes) per a 1997 USDA report. Capper-Volstead exemption described as conditioned on one-vote-per-member or an 8% dividend cap (secondary summary; Texas AG opinion reads its state version as flat one-vote). State statutes largely determine which is allowed. Arguments: proportional voting for those with more equity at risk; one-member-one-vote as cooperative democratic principle, which IRS has generally endorsed. Statute text not retrieved [U]. Sources: https://www.rd.usda.gov/sites/default/files/rr156.pdf ; https://aglawjournal.wp.drake.edu/wp-content/uploads/sites/66/2016/09/agVol01No2-Matthews.pdf ; https://nationalaglawcenter.org/wp-content/uploads/assets/bibarticles/royer_principles.pdf ; https://le.utah.gov/~2003/bills/sbillenr/SB0142.htm
- Patronage dividends vs voice: Stocksy A/C and REI/Quebec rebates tie money to patronage while voting stays per-member or per-class (see Q1 entries). Quebec supporting members get no rebate.
- Multi-stakeholder co-ops [V]: typically one-member-one-vote within a class, fixed board seats per class; minimum and maximum vote shares per class suggested to harmonise interests; allocation of governance rights between classes is a key drafting decision; a customer member may have less "skin in the game"; boards should adopt conflict-of-interest policies. Sources: https://www.co-oplaw.org/?p=8947 ; https://ccednet-rcdec.ca/resource/multi-stakeholder-co-ops/ ; https://resources.uwcc.wisc.edu/CaseStudies/MSC-Training-Needs.pdf
- Fairbnb's funder cap (one third of assembly votes) is a class-level vote ceiling (Q1 source).
- Concave weighting and plutocracy [V, preprints]: arXiv 2605.18990 "Concave is the New Linear: The Impossibility of Anti-Plutocratic DAO Governance" argues quadratic or any concave mechanism cannot withstand a Sybil adversary on permissionless chains (power grows at least linearly in holdings). Not fully read, from snippet. https://arxiv.org/pdf/2605.18990 ; https://arxiv.org/pdf/2602.09608
- Related parties / family member as customer: no source found addressing related-party voting in co-ops [U]. Only the generic conflict-of-interest policy recommendation above.
- Dominant single customer in a class: no source found [U], other than class-level caps above.
## Q3. Digital governance tooling
- Decidim [V]: census authorization by admin CSV import; participants self-initiate verification from profile; authorization handlers are pluggable (SMS code, postal-letter code); CVE-2026-45415 let a limited participant-manager alter census records (fixed in 0.30.9 / 0.31.5 / 0.32.0). Sources: https://docs.decidim.org/en/admin/participants/authorizations/census ; https://docs.decidim.org/en/admin/participants/authorizations/code_postal_letter ; https://www.wiz.io/ja-jp/vulnerability-database/cve/cve-2026-45415 . Ephemeral verifications page exists (https://docs.decidim.org/en/v0.31/admin/participants/authorizations/ephemeral_verifications), not read. Revocation behaviour not retrieved [U].
- Loomio [V]: email invite with single-use link; join requests need coordinator approval depending on privacy; reusable link bypasses approval. Source: https://help.loomio.com/en/user_manual/groups/inviting_people/index.html . No weighted voting or expiry found [U].
- Snapshot / token DAOs [V]: quadratic voting relies on proof-of-personhood; whales split across wallets; fewer than 20 delegates reportedly hold >50% of power in major DAOs; vote-escrow aligns long-term incentives but is illiquid. Sources: https://blog.tally.xyz/a-simple-guide-to-quadratic-voting ; https://www.spark.money/glossary/quadratic-voting ; https://blockeden.xyz/forum/t/1-of-token-holders-control-90-of-voting-power-across-major-daos-quadratic-voting-delegation-incentives-and-conviction-voting-havent-fixed-the-plutocracy-problem/541 (forum, low rigor).
- Decay / expiry [V]: EIP-7787 draft proposes token voting-power decay over a fixed 90-day period (draft, not deployed). Colony described as decaying reputation unless members keep contributing. Sources: https://eips.ethereum.org/EIPS/eip-7787 ; https://blog.colony.io/8-essential-voting-mechanisms-in-daos/ . A forum post describes log-decayed power for large holdings (10x holdings ~ 4x power).
- DAOstack [V]: non-transferable reputation earned by contribution; peer-reviewed retrospective "The rise and fall of DAOstack": https://peerj.com/articles/cs-3320 . Decay specifics unconfirmed [U]. Aragon: non-transferable reputation templates; claims about Aragon dissolution and ANT voting removal from a single low-quality source [U].
- Open Collective: nothing retrieved on backer voting rights or governance [U].
## Q4. Contract-funded versus donation-funded voice
- No literature found distinguishing a paying client class from a patron/donor class [U].
- Adjacent facts: Dutch sample statutes with donors (donateurs) lacking general-meeting votes (Q5); Quebec supporting members as a non-voting-benefit, no-rebate class (Q1); investor/funder classes as non-user classes with separate caps (Fairbnb, UK rulebook example: https://files.uniteddiversity.coop/Cooperatives/Multi-Stakeholder_Co-ops/go!_rules_v3.0.pdf , from search listing, not opened); Stocksy and REI tie money flows to patronage not votes; Resonate has listener class at 5 EUR/yr.
## Q5. EU / Netherlands legal and consent points
- BW 2:53: coöperatie is an association founded by notarial deed, at least two members at founding, no max (https://wetboekplus.nl/burgerlijk-wetboek-boek-2-artikel-53-oprichting-cooperatie-en-onderlinge-waarborgmaatschappij/ , https://www.viajuridica.nl/informatiesoorten/wetstoelichtingen/oprichting-cooperatie-art-2-53-2-54-bw) [V]. Articles on voting (2:38 etc.), 2:53a, member rights: text not retrieved; official page fetches gave metadata only [U].
- Admission in sample statutes [V]: board decides unless statutes assign it to the general meeting; general meeting can override a refusal; one set requires unanimity of a fully present meeting; one gives board six weeks to answer in writing. Register of members kept by the board, inspectable by members; board may record additional data beyond the list. Voting: one set denies donors votes; another lets non-qualifying members vote on certain proposals. Sources: https://www.glastuinbouwnederland.nl/content/user_upload/Komkommer_Concept_statuten_gewasco%C3%B6peratie_komkommerUA__3_.pdf ; https://rhoon.herenboeren.nl/wp-content/uploads/2024/05/Huishoudelijk-Reglement-Herenboeren-Rhoon.pdf ; https://www.kennisnetgeboortezorg.nl/wp-content/uploads/2019/05/Statuten-coo%CC%88peratie-IGO-Geboortehart.pdf ; https://raad.ridderkerk.nl/Documenten/bijlage/Bijlage-8-ledenovereenkomst.pdf (ledenovereenkomst example, not opened).
- GDPR/AVG for member registers [V, secondary]: common lawful basis cited is Art. 6(1)(b) (performance of membership agreement), sometimes plus consent for extra data; GDPR sets no fixed retention (AP position quoted), Dutch practice often keeps accounting data 7 years, rest deleted after termination; processing register practically required. Sources: https://www.kvk.nl/wetten-en-regels/ga-als-vereniging-goed-om-met-privacy-en-avg/ ; https://www.legiscope.com/blog/avg-verenigingen-stichtingen.html ; https://www.moore-drv.nl/avg-hoe-lang-mag-u-persoonsgegevens-bewaren/ . Direct Autoriteit Persoonsgegevens guidance not retrieved [U].
- Not found: coöperatie U.A. member-agreement requirements beyond statutes; relationship between customer contract and membership [U].
## Gaps (not retrieved)
Open Collective governance; Up & Go structure; Eva/Fairbnb/Resonate application steps; Capper-Volstead statute text; Italian civil code art. 2526; Quebec voting formula; Dutch BW 2:38/2:53a text; AP guidance; any source on related-party or dominant-customer voting; paid-client vs donor estates.