import { z, type EntityRef, type PlatformActorId } from '@substrat-run/contracts'; import { type ExecutorRetryPolicy, type ScopeHost } from './scope-host.js'; /** What the add path consumes, and the version it reads. */ export declare const MEMBER_ADD_REQUESTED = "member.add-requested"; /** What the remove path consumes, and the version it reads. */ export declare const MEMBER_REMOVE_REQUESTED = "member.remove-requested"; /** The delivery-journal id of the add path unless a mount names another (`executor:membership`). */ export declare const MEMBERSHIP_EXECUTOR_ID = "membership"; /** The remove path's id, derived from the add path's: `-remove`. */ export declare const membershipRemoveExecutorId: (id?: string) => string; /** The membership entity both requests are emitted on — what orders a removal after an add. */ export declare const membershipEntity: (principal: string) => EntityRef; /** * `member.remove-requested` v1 — what a vertical emits to take someone out: the role it * holds them at, and the org its invitation named. Fat (D-19), like the add. The executor * takes the role away; the org is the vertical's own vocabulary and is not touched. */ declare const memberRemoveRequestedPayload: z.ZodObject<{ principal: z.core.$ZodBranded; orgId: z.core.$ZodBranded; tenantId: z.ZodString; roleKey: z.ZodString; }, z.core.$strip>; export type MemberRemoveRequestedPayload = z.infer; export interface MembershipExecutorOptions { /** The add path's delivery-journal id (`executor:`). Default `MEMBERSHIP_EXECUTOR_ID`. */ id?: string; /** The platform identity the admin rows record as having executed the write. */ actor: PlatformActorId; /** * Where the role is assigned and removed, and the bound asked: the tenant node, and only * there. Optional, and `'tenant'` is the only value it takes. A scope-level role lives in * the scope's store while membership lives in the directory, and no single operation spans * the two, so a scope-level add could always interleave with a removal between its writes. * A scope role has its own atomic check-and-grant: `assignScopeRoleBounded`. */ level?: 'tenant'; /** * What happens to the org a request names (#2047). `'ignore'`, the default: nothing — the org * is the vertical's own vocabulary, and only the role is effected. `'join'`: an add joins it * and a removal takes the person out of it, beside the role and in the same unit, bounded by * the inviter's or remover's own live membership of it (`MembershipChange.orgId`). */ orgs?: 'ignore' | 'join'; retry?: ExecutorRetryPolicy; } /** * How far before a request a removal still wins over it (#1184): 5 minutes. A removal's fence * is stamped by the directory's clock; the request is a scope event stamped by the scope's. * The two stores share no causal order, so a tie goes to the removal and so does anything * within this skew. The cost, stated: someone removed less than this before they accept a NEW * invite is refused — resend it. Removals through the seam are also ordered by outbox id. */ export declare const MEMBERSHIP_REMOVAL_SKEW_MS: number; /** Mount the membership executor — both paths — on a host. One call, at host construction. */ export declare function registerMembershipExecutor(host: ScopeHost, options: MembershipExecutorOptions): void; export {}; //# sourceMappingURL=membership-executor.d.ts.map