Part of #589.
CONTEXT
iamnim resolves org memberships from Pantheon realm r_349832f91720 (iamnim/docs/runbooks/deploy.md:7,34). No Pantheon organization exists for Visit Flanders. The hydraorganization org ID is visit-flanders (verified live). Docs are inconsistent (visitflanders appears in Perforce infra). DECISION: the canonical Pantheon slug is visit-flanders, equal to the hydraorganization org ID, so /api/me/memberships maps to hydravenues organization_id with no translation. The Perforce host visitflanders is unchanged; it is infrastructure naming.
This is OPS WORK ONLY. No code change is expected. The pantheon store files below are listed for reading reference only, to find the CLI and the membership key shape.
ORDERING (important, do not stall on a missing user_id)
- FIRST: the Visit Flanders owner logs into iamnim once (Google OAuth or magic link). This login creates the user record in realm r_349832f91720. Membership grants need this user_id; it does not exist before the first login.
- Find the user_id for the owner in Pantheon (by email).
- Create the organization: pantheon create-organization --slug visit-flanders --realm r_349832f91720 (exact CLI form per pantheon/docs/runbooks/RUNBOOK.md).
- Grant the membership (user_id, organization_slug visit-flanders). Membership PK is (user_id, organization_slug) per pantheon/internal/store/membership.go:61-68.
- Verify: with the owner's iamnim session, GET https://iamnim.com/api/me/memberships returns organization_slug visit-flanders.
ACCEPTANCE CRITERIA
- Steps run in the order above; the login-then-grant ordering is followed and recorded in the issue comments.
- Pantheon holds org visit-flanders in realm r_349832f91720.
- The owner's /api/me/memberships response includes visit-flanders.
- The slug decision (visit-flanders canonical, visitflanders stays infra-only) is recorded in pantheon/docs/runbooks/RUNBOOK.md or the issue, so the next reader does not re-open it.
REFERENCE FILES (read only, no changes expected)
- /home/claude-user/pantheon/docs/runbooks/RUNBOOK.md
- /home/claude-user/pantheon/internal/store/membership.go
- /home/claude-user/pantheon/docs/AUTHENTICATION_AND_AUTHORIZATION.md
- /home/claude-user/iamnim/docs/runbooks/deploy.md
DONE 2026-09-01. Pantheon orgs created in realm r_349832f91720 and membership granted, so #596 could be switched on.
What was done: created org slug visit-flanders (Visit Flanders) and org slug hydra (Hydra), both with admin_email cederik@cederik.com, then granted user u_717adf7feb08 (cederik@cederik.com) membership in each. Both returned 201. Memberships now: callyouragentai, experiencenet, hydra, nimsforest, visit-flanders. The user record already existed from an earlier iamnim sign-in, so the login-then-grant ordering was already satisfied.
HOW, since Pantheon stores only a hash of its admin key and the plaintext is not on the host: iamnim mints a short-lived (299s) Pantheon realm JWT from mycelium at GET https://mycelium.nimsforest.com/api/vend/pantheon/token using mycelium_bootstrap_token from /opt/iamnim/config.yaml on land-iamnim-one (78.47.174.83). That realm JWT can create orgs and memberships inside r_349832f91720. Note it is a GET, not a POST, despite the config key being named pantheon_vend_url; a POST returns Method Not Allowed.
SLUG RULE HELD: the Pantheon slug equals the hydraorganization org id exactly, which is what lets the dashboard map a membership to a venue roster with no translation.
NOT created: yondr, cyborn and gallo-romeins-museum exist in hydraorganization but have no Pantheon org yet. Create them the same way when those partners need dashboard access.