import { TRAIT_GUARDED, TRAIT_PRICED, GOVERNED_TRAIT_URNS } from "./endpoint-cluster.js"; import { type GuardCallSeam, type GuardObligation } from "./endpoint-guard.js"; import { type EpServeGrant } from "./endpoint-service.js"; import type { EpCaller } from "./endpoint-subjects.js"; import { type AnchorResolver } from "./endpoint-signing.js"; export { TRAIT_GUARDED, TRAIT_PRICED, GOVERNED_TRAIT_URNS }; /** What a trait definition may attach to (§13.7). */ export declare const TRAIT_SELECTORS: readonly ["cluster", "command", "attribute", "event"]; export type TraitSelector = (typeof TRAIT_SELECTORS)[number]; /** The §13.7 trait definition artifact: content-addressed (its identity is * {@link traitDefinitionDigest} over the FULL artifact, signature included) and signed * (`v`/`signer`/`sig` are the §13.10 signing envelope around the normative five-field * tuple). `authority` NAMES the key that must sign every attachment of this trait — * attachment authority is distinct from definition authority by design. */ export interface TraitDefinition { v: 1; urn: string; /** CLOSURE digest of the schema bundle every attachment `value` validates against. */ valueSchema: string; selector: readonly TraitSelector[]; breakingChanges: boolean; authority: { keyId: string; }; signer: { keyId: string; }; sig: string; } /** The §13.10 trait-attachment artifact (replay matrix row: revision-bound evidence, * replaced only by an authorized contract revision). `contractDigest` is the declaring * cluster document's complete CLOSURE digest — the binding that makes an attachment for * one revision unusable for any other. */ export interface TraitAttachment { v: 1; space: string; endpoint: string; command: string; contractDigest: string; traitUrn: string; value: unknown; signer: { keyId: string; }; ts: number; sig: string; } /** Fetch one contract-store artifact by digest (the same read seam serve authorization * uses): `undefined` = not readable (fail closed at the caller). */ export type TraitArtifactReader = (digest: string) => Promise | unknown; /** * Verify a trait DEFINITION (§13.7/§13.10), fail closed: shape (closed schema), the signer * resolved FRESH in the anchor registry (role `traits`, window at verification time — a * definition is timeless content, its authority must be live), the signer's traits-scope * covering the urn's reverse-DNS domain (this is what makes `ai.cotal.*` operator-only and * a third-party urn its registered owner's), and the D28 signature. Returns the frozen, * provenance-branded definition; every attachment verifier REQUIRES the brand. */ export declare function verifyTraitDefinition(raw: unknown, opts: { resolveAnchor: AnchorResolver; now?: number; }): Promise; /** True iff this exact object came out of {@link verifyTraitDefinition}. */ export declare function isVerifiedTraitDefinition(def: unknown): def is TraitDefinition; /** The definition's content address (§13.7): the artifact digest over its FULL RFC 8785 * canonical form, signature included — the value a by-digest reference names. */ export declare function traitDefinitionDigest(def: TraitDefinition): string; /** * Verify one governed trait ATTACHMENT against its verified definition and the EXPECTED * binding coordinates (§13.7/§13.10), fail closed on every §13-acceptance adversarial class: * - substitute: `space`/`endpoint`/`command` must equal the expected target — an attachment * signed for one command can never gate (or satisfy) another; * - stale digest: `contractDigest` must equal the CURRENT declaring cluster's closure * digest — a prior revision's attachment is revision-bound evidence, never carried over; * - forge: the signer MUST BE the definition's NAMED authority, resolved fresh (role * `traits`, window checked at VERIFICATION time — never the signer-asserted `ts`, which is * self-attested and would let an expired predecessor key backdate or a not-yet-valid * successor future-date past rotation, §13.10 — revocation immediate), its traits-scope * must cover the urn, and the D28 signature must verify over the exact received bytes; * - downgrade: within a digest the value is signature-bound; a value the schema rejects * fails here, and cross-revision weakening is caught at the trusted registration write * (registerServiceInstance's governed-continuity seam), not from a caller-supplied prior; * - selector: the definition must admit a `command` target. * The `value` is validated against the definition's `valueSchema` bundle, read and compiled * through the SAME digest-verified path serve authorization uses. */ export declare function verifyTraitAttachment(raw: unknown, opts: { definition: TraitDefinition; expect: { space: string; endpoint: string; command: string; contractDigest: string; }; resolveAnchor: AnchorResolver; readArtifact: TraitArtifactReader; /** Verification time (ms epoch) the anchor window is checked at; defaults to `Date.now()`. * NEVER the attachment's self-attested `ts` (§13.10: rotation closes a key's window, and a * signer cannot be trusted to timestamp its own signing act). */ now?: number; }): Promise; /** True iff this exact object came out of {@link verifyTraitAttachment}. */ export declare function isVerifiedTraitAttachment(att: unknown): att is TraitAttachment; /** The verified governed surface of ONE serve grant: command → governed traitUrn → its * verified attachment. Opaque to construction — only {@link verifyGovernedSurface} brands * one, and the serve boundary refuses anything unbranded or bound to a different grant. * * A DEEP-FROZEN, NULL-PROTOTYPE nested record, never a `Map`: `Object.freeze` does not disable * a Map's `set`/`delete`/`clear`, so a WeakMap brand over a mutable Map would attest provenance * WITHOUT integrity — a caller could delete a governed command after verification and the gate * would then see it as ungoverned and run the handler unguarded. And a plain `{}` record would * resolve the valid command token "constructor" through `Object.prototype`, landing attachment * state on the GLOBAL `Object` function instead of an own frozen entry. The frozen null-proto * record is genuinely immutable and every lookup an own-property read, so the brand means * integrity. */ export interface EpGovernedSurface { commands: Readonly>>>; } /** * Verify a serve grant's WHOLE governed surface (§13.7, fail closed, both strip directions): * every granted command's DECLARED governed traits must each have exactly one verified * attachment bound to that command's declaring closure digest (a declared-but-unattached * governed trait is a strip or an unverifiable annotation — refuse before effect), and every * supplied attachment must land on a command that DECLARES its trait (an attached-but- * undeclared governed trait means the self-published descriptor dropped an authority's * annotation — equally a strip). Duplicates, unknown commands, non-governed urns, and * missing definitions all refuse. Returns the branded surface, bound to exactly this grant's * identity coordinates; {@link assertGovernedSurfaceFor} is the serve-side check. * * This verifies the CURRENT surface's declaration<->attachment coherence (both strip directions * WITHIN a revision). Cross-REVISION governed-continuity (a re-registration may not strip an * authority-imposed trait from a surviving command, §13.7) is enforced at the TRUSTED registration * write (registerServiceInstance's governed-continuity seam) against the registry's prior * spec — NOT here, and NOT from a caller-supplied prior surface, which the owner could forge by * claiming "first governance". */ export declare function verifyGovernedSurface(args: { serve: EpServeGrant; definitions: readonly TraitDefinition[]; attachments: readonly unknown[]; resolveAnchor: AnchorResolver; readArtifact: TraitArtifactReader; now?: number; }): Promise; /** Refuse a governed surface that {@link verifyGovernedSurface} did not produce FOR THIS * grant: brand first (structure carries no verification), then the identity bond — a * surface verified for another instance, epoch, or registration revision never gates this * one (a re-registration re-verifies; the fresh grant demands a fresh surface). */ export declare function assertGovernedSurfaceFor(surface: EpGovernedSurface, serve: EpServeGrant): void; /** The reference guard/proof seam deadline (§13.8: reference default call deadline 15s; * overridable, never removable) when the request carries no tighter budget. A governed gate * MUST be bounded — a never-settling seam is timeout→deny, never a hung request. */ export declare const REFERENCE_GOVERNED_SEAM_DEADLINE_MS = 15000; /** The GUARD wiring (§13.6/§13.9): the raw class-call seam to the guard endpoint plus the * trust-anchor resolver its OBLIGATION VERIFICATION requires. There is ONE guard gate, * {@link import("./endpoint-guard.js").runGuardGate} — this bundle is what the serve boundary * hands it. The seam returns the guard's RAW answer plus the broker-authenticated responder * (derived from the reply subject by the transport layer, never from the body); the gate owns * ALL parsing and verification, so a transport wiring can never surface an unverified * obligation to a handler. `now` is the verification clock for obligation/anchor windows * (default `Date.now()`, injectable like every other verification-time clock here). */ export interface EpGuardWiring { call: GuardCallSeam; resolveAnchor: AnchorResolver; now?: () => number; } /** The priced-proof SEAM (§13.9): verify the `auth`-slot payment proof — an INDEPENDENTLY * verifiable artifact, never a bare "settled" assertion (§13.10). The verifier owns the * declared replay policy (matrix default: one-use per request id — journal the redemption). * Token formats and payment rails are extensions behind this seam. */ export type EpPricedProofVerify = (q: { endpoint: string; command: string; caller: EpCaller; requestId: string; /** The `auth` slot exactly as carried. */ proof: string; /** The verified attachment's value — the priced terms. */ value: unknown; }) => Promise | boolean; /** What the serve boundary wires to enforce its governed surface: the branded surface plus * the hooks its traits demand ({@link import("./endpoint-serve.js").serveEndpoint} refuses * at construction if a governed command's hook is missing — fail closed at wiring time, * not at first request). `verifyPaymentProof` is the JOURNAL-side gate's hook: priced implies * journal-class (§13.10 — a receipt derives from the journaled acceptance), so the ephemeral * rail never demands it; serveEndpoint refuses an ephemeral priced command outright. */ export interface EpTraitEnforcement { governed: EpGovernedSurface; guard?: EpGuardWiring; verifyPaymentProof?: EpPricedProofVerify; } /** * The fail-closed pre-effect gate (§13.7/§13.9): run once per accepted request, AFTER args * validation, target currency, and mode authorization, immediately BEFORE the handler — for * calls and casts alike (casts have effects too). Guard FIRST, then priced (deliberate: a * guard deny must never burn a one-use payment proof). Every anomalous answer refuses: * - guarded: THE gate is {@link runGuardGate} — the guard's raw answer is parsed CLOSED and * every obligation is VERIFIED (D28 signature, anchor role/scope, validity window, * space + request binding) before it can reach a handler; wiring absent, seam throw, * timeout, garbled answer, or an unverifiable obligation = DENY (`permission-denied`); * `deny` = `permission-denied`; `hold` = `failed-precondition` on THIS rail (hold converts * an ACTION to waiting on a guard-owned checkpoint, §13.6 — the ephemeral rail cannot * wait; the action composite's own gate, `gateGoalExecution`, routes hold); * - priced: absent `auth` slot, seam absent, seam throw, non-boolean or false answer = * `permission-denied`; a proof is verified, never assumed. * Both gates are BOUNDED by `deadlineMs` (the request budget, or the §13.8 reference * default): a never-settling extension becomes deny at the bound, never a hung request. * Returns the guard's VERIFIED obligations for the handler context. Receipt emission for * priced commands is the §13.10 receipts slice (D9), not gated here. */ export declare function assertGovernedPreEffect(args: { enforcement: EpTraitEnforcement; endpoint: string; command: string; caller: EpCaller; requestId: string; /** The space the request is served in — guard obligations are space-bound (§13.6). */ space: string; auth?: string; /** The seam bound (ms); defaults to {@link REFERENCE_GOVERNED_SEAM_DEADLINE_MS}. */ deadlineMs?: number; }): Promise<{ obligations?: readonly GuardObligation[]; }>; //# sourceMappingURL=endpoint-traits.d.ts.map