Skip to content

Add appeals@ Google Group for Code of Conduct ban appeals#123

Draft
tadasant wants to merge 1 commit into
modelcontextprotocol:mainfrom
tadasant:appeals-google-group
Draft

Add appeals@ Google Group for Code of Conduct ban appeals#123
tadasant wants to merge 1 commit into
modelcontextprotocol:mainfrom
tadasant:appeals-google-group

Conversation

@tadasant

@tadasant tadasant commented Jun 20, 2026

Copy link
Copy Markdown
Member

What & why

Adds appeals@modelcontextprotocol.io as an email Google Group so that banned or external users have an out-of-band channel to appeal Code of Conduct actions. When someone is blocked at the GitHub org level they lose access to all repos/issues/PRs, so the appeals channel must be email — it cannot live in GitHub.

This mirrors the existing antitrust@ / catch-all@ email-group setup: an isEmailGroup: true group with no new GoogleConfig fields, and an explicitly curated member list (exactly like the hand-listed antitrust@ members at the bottom of users.ts).

Behavior this unblocks

  • Anyone can email in — including external/banned users. The existing isEmailGroup branch in google.ts already sets whoCanPostMessage: ANYONE_CAN_POST, so no google.ts change is needed.
  • Delivers to the current moderation + lead-maintainer teamROLE_IDS.APPEALS is added to a curated set of 8 member entries (see below). Membership is not derived from the MODERATORS/LEAD_MAINTAINERS roles, because those roles currently include emeritus / former members who should not receive appeals (e.g. an emeritus lead maintainer).
  • Message archive is restricted to group members — for isEmailGroup groups, google.ts sets whoCanViewGroup: 'ALL_MEMBERS_CAN_VIEW' (badly named in the Google API; it controls who can read group messages). Only the group's members can read the appeal threads.
  • Member roster is domain-visible (not the messages)whoCanViewMembership: 'ALL_IN_DOMAIN_CAN_VIEW' (unconditional in google.ts) lets anyone with an @modelcontextprotocol.io address see who is in the group. This governs the membership list only, not the archive.

Curated membership

ROLE_IDS.APPEALS is added to these 8 users.ts entries:

Person Entry Role Resolves to
David Soria Parra dsp-ant lead maintainer david@
Den Delimarsky localden lead maintainer den@
Tadas Antanavicius tadasant moderator tadas@
Ola Hungerford olaservo moderator ola@
Shaun Smith evalstate moderator shaun.smith@
Cliff Hall cliffhall moderator cliff@
Jonathan Hefner jonathanhefner moderator ⚠️ no mailbox yet
Peder pederhp moderator ⚠️ no mailbox yet

⚠️ jonathanhefner and pederhp have no managed @modelcontextprotocol.io mailbox and no personal email: in users.ts, so google.ts (if (!memberEmail) return) produces no group membership for them — they will not receive appeals mail until they're provisioned a mailbox or a personal email: is added. APPEALS is on their entries so they auto-join the moment they get an address. The other 6 entries resolve to live mailboxes: cliff@, david@, den@, ola@, shaun.smith@, tadas@.

The change — three files

  1. src/config/roleIds.ts — add APPEALS: 'appeals' to ROLE_IDS (the RoleId union derives from this, so no other type edits needed).
  2. src/config/roles.ts — add an isEmailGroup role { id: ROLE_IDS.APPEALS, description: 'Code of Conduct ban appeals inbox', google: { group: 'appeals', isEmailGroup: true } }, alongside ANTITRUST / CATCH_ALL.
  3. src/config/users.ts — append ROLE_IDS.APPEALS to the 8 curated entries above.

Scope kept intentionally minimal

  • No changes to google.ts — the existing isEmailGroup branch and membership loop already produce everything needed.
  • No new GoogleConfig fields.
  • No changes to anyone's base MODERATORS/LEAD_MAINTAINERS/CORE_MAINTAINERS roles — appeals membership is curated independently, so this PR does not touch unrelated group/GitHub-team memberships.

Fast follows (deliberately deferred)

  1. Provision mailboxes (or add personal emails) for jonathanhefner and pederhp so they actually receive appeals. Out of scope here because it requires their input / a GWS account decision.
  2. Reconcile stale role data — the MODERATORS / LEAD_MAINTAINERS roles include people who are no longer active in those capacities (an emeritus lead maintainer still carries LEAD_MAINTAINERS + CORE_MAINTAINERS; some MODERATORS holders are maintainers, not community moderators). Cleaning this up affects GitHub teams and other group memberships, so it's a separate change. Note: this is also why appeals membership is curated rather than role-derived — a naive auto-sync would re-add the very people this PR excludes.
  3. Auto-synced membership (only after Add antitrust email group #2) — once the role data reflects reality, add an inheritMembersFrom?: readonly RoleId[] field to GoogleConfig so appeals membership tracks the roles automatically instead of by hand.
  4. Maintainer-wide archive readability — a per-group override setting whoCanViewGroup to ALL_IN_DOMAIN_CAN_VIEW (today isEmailGroup hard-codes ALL_MEMBERS_CAN_VIEW) so any maintainer can browse the appeals archive for transparency. No precedent in the repo, deferred.
  5. (Optional) Reply-as-the-group — a unified From: appeals@ reply address via Collaborative Inbox or per-user send-as aliases; needs a one-time Workspace admin step.

Verification

  • npm run check (format:check + validate + test) passes: Prettier clean, config validation green (role references + member ordering), 23/23 config tests pass.
  • google.ts is unchanged — git diff main --name-only shows only src/config/roleIds.ts, src/config/roles.ts, src/config/users.ts.
  • Exactly 8 users.ts entries gained ROLE_IDS.APPEALS: dsp-ant, localden, tadasant, olaservo, evalstate, cliffhall, jonathanhefner, pederhp. Justin (jspahrsummers, emeritus), Paul (pcarleton), and bhosmer-ant are intentionally not members.
  • Resolved deliverable mailboxes (via google.ts email resolution): 6cliff@, david@, den@, ola@, shaun.smith@, tadas@. jonathanhefner / pederhp resolve to none (flagged above).
  • npx tsc on the config files is clean. The full npm run build reports one pre-existing, unrelated error — Cannot find module '@pulumi/googleworkspace' in google.ts — because the generated Pulumi SDK under sdks/googleworkspace isn't built in a non-deploy checkout; it reproduces on a clean main.

Draft: opening for review of the approach before it's applied. No pulumi up was run — deployment happens in CI on merge.

Adds appeals@modelcontextprotocol.io as an email Google Group so banned
or external users have an out-of-band channel to appeal Code of Conduct
actions even after an org-level GitHub block. Mirrors the existing
antitrust@/catch-all@ email-group setup (isEmailGroup, no new GoogleConfig
fields).

Membership is curated explicitly (like the antitrust@ members) to the
current moderators and active lead maintainers, rather than derived from
the MODERATORS/LEAD_MAINTAINERS roles, since those roles include emeritus
and former members who should not receive appeals.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tadasant tadasant force-pushed the appeals-google-group branch from 43d2f38 to 810462c Compare June 21, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant