v2.39.0
Org membership, grants & whoami — the org-owned control plane, client side
Phase 2 of the org-owned control plane (gateway org-member-management, live + prod-verified). A wallet authenticates (SIWX → a control-plane principal); the org (billing account) owns projects, and authorization is an org membership role or a per-project grant. Additive — SIWX auth is unchanged.
SDK (@run402/sdk)
r.org—whoami()(GET/agent/v1/whoami→{ principal, memberships[], authenticator_id }),list(),members(ba),addMember(ba, { wallet, role? }),setRole(ba, principalId, role),removeMember(ba, principalId). Member mutations are owner-gated.r.grants(+ project-scopedr.project(id).grants) —create(projectId, { wallet, capability, policy?, expiresAt? }),revoke(projectId, grantId)— per-project capability grants for agent/CI principals.- The local, network-free
r.whoami()is unchanged; the remote principal call isr.org.whoami(). - New exported types:
OrgRole,Principal,OrgMembership,OrgMember,WhoAmIResult,ProjectGrant(+ inputs/results).409 LAST_OWNER/400 VALIDATION_ERRORsurface asApiErrorwith theircode.
CLI (run402)
run402 org {whoami,list,members,add-member,set-role,remove-member} and run402 grants {create,revoke}.
MCP (run402-mcp)
8 tools: whoami, list_orgs, list_org_members, add_org_member, set_org_member_role, remove_org_member, create_project_grant, revoke_project_grant. Plus LAST_OWNER guidance.
Note: membership-add is by wallet — the gateway has no invite route yet (email-first invite is a separate later change), so the surface is add-member, not invite.
Addresses #434 (the deferred org-management surface).