export { assertLifecycleToken, mintLifecycleUid } from "./subjects.js"; /** The v0.4 wire version this surface targets. Advertised (§6 `protocolVersion`) only at the * §13.11 cutover — a change signal, not negotiation; nothing pre-cut should flip the card. */ export declare const PROTOCOL_VERSION_V04 = "0.4"; /** Reserved command names (§13.2): every endpoint serves `describe` (§13.7); `cancel` is the * action-composite control command (§13.6). */ export declare const RESERVED_COMMANDS: readonly ["describe", "cancel"]; /** An issued generation: 32 lowercase hex characters of issuer-chosen entropy (at least 128 * bits). An identifier the broker pins in a subject, never a bearer secret. */ export declare function assertGeneration(generation: string, what?: string): string; /** Maximum total subject size (bytes) on the endpoint rails; builders throw above it. */ export declare const MAX_EP_SUBJECT_BYTES = 1024; /** Validate a dotted endpoint NAME (one or more DNS-shaped labels; `_` never appears in a label) * and return its wire TOKEN (`.` → `_`, bijective because labels cannot contain `_`). Single-label * names are reserved for reference-implementation endpoints; a third-party name MUST be * reverse-DNS — that is an AUTHORITY rule enforced at mint (§13.9), not a shape difference, so * both build here. */ export declare function endpointToken(name: string): string; /** Inverse of {@link endpointToken}: recover the dotted endpoint name from its wire token. */ export declare function endpointNameOf(token: string): string; export declare function assertCommandToken(command: string): string; export declare function assertNonce(nonce: string): string; export declare function assertIdToken(v: string, what?: string): string; /** The provisioner-assigned grant id `` (§13.9). Deliberately SEPARATOR-FREE ([a-z0-9]): * the `eve_---` and `rec_--` reader-durable names carry it adjacent * to other soft components across `-`, so a `-` (or `_`) inside `` would make the name * non-injective (`eve_-a-b-c-0` could be endpoint `a-b`/gid `c` OR endpoint `a`/gid `b-c`). * Constraining `` to a separator-free grammar keeps the tuple encoding unambiguous while * `` is `-`-free (leading) and `` is digits (trailing). */ export declare function assertGrantId(v: string, what?: string): string; /** `` uses the command-token grammar (§13.2). */ export declare function assertPoolToken(pool: string): string; /** The shared owner/actor token validator for this grammar (§13.2 token bounds): the base * owner-token grammar plus the 64-character rail bound. Grant builders MUST route through the * same validator as subject builders, so the two can never diverge on what they admit. */ export declare function assertBoundedOwner(v: string, what: string): string; /** The three forge-locked caller tokens every request and journal submission carries: * principal + lifecycle UID (§13.1). */ export interface EpCaller { owner: string; actor: string; uid: string; } /** The six reserved authorization-mode tokens. Disjoint from every spec-conformant owner token * (`local` or `u_`+base32 per §2, never a bare mode word); the implementation's owner validator * also admits legacy principal tokens, so the parser's discrimination rests on membership in * this set PLUS each mode's pinned arity, not on the owner grammar alone. */ export declare const EP_AUTHZ_MODES: readonly ["self", "owner", "any", "child", "ledger", "handle"]; export type EpAuthzMode = (typeof EP_AUTHZ_MODES)[number]; /** Is `m` a registered targeted-command authorization mode? Consults the PRIVATE module-load set, * never the live export, so a post-import mutation of {@link EP_AUTHZ_MODES} cannot widen the * modes a cluster document may declare (the afa715b integrity class). */ export declare function isEpAuthzMode(m: string): boolean; /** Per-mode pinned target-token arity: `self` carries none (the caller triple IS the target); * `owner`/`any`/`child`/`ledger` pin one ``; `handle` pins the full redemption-minted * target triple. The target's lifecycle UID is otherwise body-carried (§13.3), never a token. */ export type EpTarget = { mode: "self"; } | { mode: "owner" | "any" | "child" | "ledger"; tOwner: string; } | { mode: "handle"; tOwner: string; tActor: string; tUid: string; }; /** The caller triple as validated subject tokens — the ONE validation every caller-scoped * subject and filter goes through. */ export declare function callerTokens(caller: EpCaller): string[]; /** A caller that rides the versioned rail (SPEC 13.15): the triple plus its accepted generation. * Every subject and grant builder emits the `ep.v1` form exactly when the caller carries this * field, so one caller value decides both the subject a client publishes and the rows a mint * grants; the two cannot disagree. */ export interface IssuedCaller extends EpCaller { readonly generation: string; } export declare function isIssuedCaller(caller: EpCaller): caller is IssuedCaller; /** The caller block as it rides the wire: the triple, plus the issued generation on the * versioned rail (SPEC 13.15). The generation is ALWAYS the token before the nonce, for every * mode, so a reader takes it at a fixed offset from the tail without knowing the mode's arity. */ export declare function callerRailTokens(caller: EpCaller): string[]; /** The `ep` plane tokens for a caller: `["ep", "v1"]` on the issued rail, `["ep"]` on the legacy * one. The version token sits right after the plane so `ep.one`/`ep.all`/`ep.inst`/`ep.reply` * stay unambiguous by discriminator, never by counting extra tokens. */ export declare function epPlaneTokens(caller: EpCaller): string[]; /** The versioned-rail discriminator (SPEC 13.15): `cotal..ep.v1..…`. It versions the * issued-bound rail encoding, not the protocol or the workflow language. */ export declare const EP_RAIL_V1 = "v1"; /** Where a request routes (never which verb it is — the verb rides the envelope, §13.3/§13.5): * `one` = queue-group anycast to exactly one class member; `all` = scatter to every instance; * `inst` = one instance by its stable `(endpoint, instanceId)` address (single-owner endpoint * names carry no owner tokens). */ export type EpRoute = { mode: "one" | "all"; } | { mode: "inst"; instanceId: string; }; /** Build a request subject (class, scatter, or instance form; targeted iff `target` is given). */ export declare function epRequestSubject(space: string, req: { route: EpRoute; endpoint: string; command: string; target?: EpTarget; caller: EpCaller; nonce: string; }): string; /** Build a reply subject: the responder's own endpoint/instance/epoch prefix plus the caller * triple and nonce. Use {@link deriveReplySubject} to answer a request — replies MUST derive * from the authenticated request subject, never from a transport- or payload-supplied target. */ export declare function epReplySubject(space: string, r: { endpoint: string; instanceId: string; epoch: number; caller: EpCaller; nonce: string; }): string; /** Deterministic reply derivation (§13.2 "Replies"): copy the caller triple + nonce off the * broker-authenticated PARSED request and prefix the responder's own instance identity. Taking * a {@link ParsedEpRequest} (not a raw string) makes the confused-deputy boundary structural: * there is no argument through which a payload-supplied reply target could arrive. */ export declare function deriveReplySubject(space: string, request: ParsedEpRequest, responder: { instanceId: string; epoch: number; }): string; /** The AUTH plane's endpoint name (#350). The plane serves the GENERIC "retire a lifecycle" * operation here after §13.11's hard cut retired the `ctl` rail it used to serve on; the rows * that served it on `ctl.auth-admin` were spec defects written onto a deleted rail. Single-label, * single-owner, no owner tokens in the subject — the `manager` / `delivery` precedent. */ export declare const AUTH_ENDPOINT = "auth"; /** The one command the auth endpoint serves. The operation was already generic — "retire a * lifecycle (owner, actor, lifecycleUid)" — so it maps 1:1 with no vocabulary invention. It rides * authz mode `handle` (arity 3), the exact argument tuple it takes: `owner`/`any` resolve against * the CURRENT mapping, which is the wrong semantics for retiring a NAMED incarnation. */ export declare const EP_CMD_RETIRE_LIFECYCLE = "retire-lifecycle"; /** The class rail's canonical queue group: the endpoint-name token. Serve subscriptions to the * `one` rail are queue-qualified ONLY (§13.9) — no credential may plain-subscribe it, which is * what keeps per-request nonces visible only to the queue-selected instance. */ export declare function epClassQueueGroup(endpoint: string): string; /** Subscription filter for a class (`one`) or scatter (`all`) serve. */ export declare function epServeFilter(space: string, mode: "one" | "all", endpoint: string): string; /** Subscription filter for one instance's own request rail. */ export declare function epInstanceServeFilter(space: string, endpoint: string, instanceId: string): string; /** A caller's reply-read filter — its OWN rail only, exact arity (no `>` tail admits subjects * outside the grammar): `ep.reply.*.*.*....*`. */ export declare function epCallerReplyFilter(space: string, caller: EpCaller): string; /** A responder's reply-publish pattern — its own instance triple and epoch pinned, all caller * suffixes spanned (addressing is confined by nonce possession, §13.2): exact arity. */ export declare function epResponderReplyPattern(space: string, endpoint: string, instanceId: string, epoch: number): string; /** The responder's reply-publish pattern on the VERSIONED rail (SPEC 13.15): one more spanned * token, the generation, between the caller triple and the nonce. Exact arity, like the legacy * row; a serve credential carries both so it answers whichever rail a request arrived on. */ export declare function epResponderIssuedReplyPattern(space: string, endpoint: string, instanceId: string, epoch: number): string; /** Serve filters on the VERSIONED rail (SPEC 13.15): the same three shapes as the legacy rail * with the version token after the plane. Served beside the legacy ones by every endpoint. */ export declare function epIssuedServeFilter(space: string, mode: "one" | "all", endpoint: string): string; export declare function epIssuedInstanceServeFilter(space: string, endpoint: string, instanceId: string): string; export type EpTimerPhase = "schedule" | "armed" | "fire"; export type EpSessionDir = "in" | "out"; /** Events: `epe....` — the publishing instance's identity * and epoch are forge-locked subject tokens (stale-epoch events are attributably stale). */ export declare function epeSubject(space: string, endpoint: string, instanceId: string, epoch: number, topic: string[]): string; /** Canonical facts: `epf..` — publishable only by the mediated writer (§13.9). */ export declare function epfSubject(space: string, endpoint: string, topic: string[]): string; /** Journal submissions: `epj..[.[.]]...` — * directly publishable by capability holders and explicitly UNTRUSTED (§13.4); a targeted * command carries the same authz/target block as its request forms, no nonce. */ export declare function epjSubject(space: string, j: { endpoint: string; command: string; target?: EpTarget; caller: EpCaller; }): string; /** Timers: `ept.....` (§13.2). */ export declare function eptSubject(space: string, endpoint: string, instanceId: string, epoch: number, timerId: string, phase: EpTimerPhase): string; /** Record writes: `epr.....` — the instance's * epoch-pinned mediated record-writer ingress (§13.9 reads the epoch off this subject). */ export declare function eprSubject(space: string, endpoint: string, instanceId: string, epoch: number, kind: string, qualifier?: string[]): string; /** Contract artifacts: `epc.` — one immutable artifact per subject; the token is the * SHA-256 hex (the `sha256:` prefix is not a subject token, §13.7). */ export declare function epcSubject(space: string, digestHex: string): string; /** Work pools: `epw......` — the trailing four tokens * are the item's ACCEPTANCE IDENTITY (the accepted submission's caller triple + request id). */ export declare function epwSubject(space: string, endpoint: string, pool: string, acceptance: EpCaller & { id: string; }): string; /** Sessions: `eps....` (§13.6). * * This is the ONLY session-subject builder, and deliberately so. §13.6 states that both sides of * a session hold only redemption-minted per-session credentials and that no standing EPS grant * exists on either side; the §13.9 matrix requires this exact subject on all four legs (caller * `in` publish, serving `in` subscribe, serving `out` publish, caller `out` subscribe). There was * a sibling builder here that emitted `eps..*..` for a standing serving * writer, and it is REMOVED rather than left unused: while a wildcard-session subject is * constructible, the standing grant it authorizes is one edit away from returning. `assertIdToken` * refuses a wildcard token, so a caller cannot smuggle one through `sessionId` either. */ export declare function epsSubject(space: string, endpoint: string, sessionId: string, epoch: number, dir: EpSessionDir): string; export interface ParsedEpRequest { plane: "request"; /** Present exactly when the subject rode the versioned `ep.v1` rail (SPEC 13.15); its value is * the rail version token. `caller` then carries the generation the broker pinned. */ rail?: typeof EP_RAIL_V1; route: "one" | "all" | "inst"; endpoint: string; /** Present iff `route === "inst"`. */ instanceId?: string; command: string; /** `null` = untargeted form (no authz token). */ target: EpTarget | null; caller: EpCaller; nonce: string; } export type ParsedEp = ParsedEpRequest | { plane: "reply"; rail?: typeof EP_RAIL_V1; endpoint: string; instanceId: string; epoch: number; caller: EpCaller; nonce: string; } | { plane: "event"; endpoint: string; instanceId: string; epoch: number; topic: string[]; } | { plane: "fact"; endpoint: string; topic: string[]; } | { plane: "journal"; endpoint: string; command: string; target: EpTarget | null; caller: EpCaller; } | { plane: "timer"; endpoint: string; instanceId: string; epoch: number; timerId: string; phase: EpTimerPhase; } | { plane: "record"; endpoint: string; instanceId: string; epoch: number; kind: string; qualifier: string[]; } | { plane: "contract"; digestHex: string; } | { plane: "work"; endpoint: string; pool: string; acceptance: EpCaller & { id: string; }; } | { plane: "session"; endpoint: string; sessionId: string; epoch: number; dir: EpSessionDir; }; /** * Parse a v0.4 endpoint-surface subject into its typed shape, or `null` for anything that is not * one — including the retired v0 `ctl.>`/`control.>` planes, which this parser deliberately does * not know. `null` means the subject has no sender and MUST NOT be handled (§13.2). */ export declare function parseEpSubject(subject: string): ParsedEp | null; //# sourceMappingURL=endpoint-subjects.d.ts.map