import { i as KrikosOptions, K as Krikos, e as AgentStatus, j as KvLike, S as StateBackend } from './types-iaO2gHBL.js'; /** * The Krikos engine: an identity registry with an enforced lifecycle state machine, declarative * capability authorization, and a hash-chained audit trail, over a pluggable state backend. * * Design invariants, all load-bearing: * - Deterministic: the engine never reads the wall clock or the global random generator. Time * comes from an injected `clock`, ids from a seeded counter. Two registries with the same seed, * clock, and operations produce byte-identical snapshots. * - Immutable records: an agent is never mutated in place. Every transition builds a fresh frozen * record and swaps it in, so a snapshot taken at any instant is a stable view. * - Fail-closed authorization: {@link Krikos.can} returns true only for an `active` agent that is * not past its expiry and declares an admitting capability. Expiry is enforced on the read even * before an explicit sweep, regardless of the `autoExpire` option. * - Append-only audit: every operation appends one frozen, hash-chained event. The trail is never * rewritten or pruned. * - Non-fatal persistence: a save fault never crashes the host or aborts an in-memory operation. * * @packageDocumentation */ /** * Creates a Krikos registry. * * With the default in-memory backend the registry is immediately usable and synchronous. With a * persistent backend ({@link import('../state/file.js').fileState} or * {@link import('../state/kv.js').kvState}), call {@link Krikos.flush} once before the first read * or write to guarantee the prior snapshot has been restored. * * @param options - See {@link KrikosOptions}. * @returns A {@link Krikos} registry. */ declare function createKrikos(options?: KrikosOptions): Krikos; /** * Error model for Krikos, the identity registry and lifecycle manager for fleets of Massive * Intelligence (IM) agents and non-human entities (NHE). * * Krikos throws exactly one error class so that host applications can catch and branch on a * single type, then dispatch on the stable machine-readable {@link KrikosError.code}. New codes * may be added in minor versions, so consumers must treat the code space as open and fall back * gracefully on codes they do not recognize. * * @packageDocumentation */ /** * The only error type thrown by Krikos. * * Invariants: * - `name` is always the literal string `'KrikosError'`, safe for cross-realm checks where * `instanceof` fails (multiple bundles, workers, iframes). * - `code` is a stable, machine-readable, SCREAMING_SNAKE identifier prefixed with `ERR_`. * It never changes meaning across versions, although new codes may appear in minors. * - `message` is human-readable English prose intended for logs, never for parsing. * * @example * ```ts * try { * krikos.activate(id); * } catch (error) { * if (error instanceof KrikosError && error.code === 'ERR_INVALID_TRANSITION') { * // The agent cannot move to active from its current lifecycle state. * } * } * ``` */ declare class KrikosError extends Error { /** * Stable machine-readable error code, for example `'ERR_INVALID_TRANSITION'`. * * Branch on this field, never on `message`. The code space is minor-extensible. */ readonly code: string; /** * @param message - Human-readable description of what went wrong and how to fix it. * @param code - Stable machine-readable code, see {@link KrikosError.code}. */ constructor(message: string, code: string); /** * Builds a {@link KrikosError} with code `'ERR_INVALID_INPUT'`. * * Used for every caller-side contract violation: an agent with no name, an empty capability * name, a non-finite expiration timestamp, a capability action that is not a string, and any * other input the type system cannot reject for untyped JavaScript callers. * * @param message - Human-readable description of the invalid input. * @returns A new error instance, never thrown by this factory itself. */ static invalid(message: string): KrikosError; /** * Builds a {@link KrikosError} with code `'ERR_NOT_FOUND'`. * * Used when a caller references an agent by id that the registry does not hold, for example * activating an id that was never issued. * * @param message - Human-readable description of what was not found. * @returns A new error instance, never thrown by this factory itself. */ static notFound(message: string): KrikosError; /** * Builds a {@link KrikosError} with code `'ERR_INVALID_TRANSITION'`. * * Used when a lifecycle operation is requested from a state that does not allow it, for * example resuming an agent that was revoked, or activating one that is archived. The * registry stays consistent; the offending transition is rejected whole. * * @param message - Human-readable description of the illegal transition. * @returns A new error instance, never thrown by this factory itself. */ static transition(message: string): KrikosError; /** * Builds a {@link KrikosError} with code `'ERR_CONFLICT'`. * * Used when an operation collides with existing state, for example issuing an agent with an * explicit id that is already registered. * * @param message - Human-readable description of the conflict. * @returns A new error instance, never thrown by this factory itself. */ static conflict(message: string): KrikosError; /** * Builds a {@link KrikosError} with code `'ERR_LIMIT_REACHED'`. * * Used when an operation would exceed a configured bound, for example issuing past * `maxAgents`. The registry stays consistent; the offending write is rejected whole. * * @param message - Human-readable description of the limit that was hit. * @returns A new error instance, never thrown by this factory itself. */ static limit(message: string): KrikosError; } /** * The Krikos lifecycle state machine: the single source of truth for which agent status * transitions are legal. * * An agent identity moves through a small, explicit set of states. Modeling the legal moves as * data, instead of scattering `if` checks through the engine, means the rules are auditable in * one place and the same table answers both "may I do this?" and "what could I do next?". * * @packageDocumentation */ /** * Adjacency list of legal transitions, keyed by source state. * * - `provisioned` may activate, or be revoked before ever going live, or expire, or archive * (a provisioned identity that is no longer wanted can be retired directly). * - `active` may suspend, revoke, expire, or rotate-in-place (rotation is not a state change, * handled separately; active is listed as its own target to express the no-op identity move). * - `suspended` may resume to active, be revoked, or expire. * - `expired` may be renewed back to active (its expiry extended) or archived. * - `revoked` may only be archived; revocation is permanent. * - `archived` is terminal. * * The targets are the states reachable by an operator-driven transition. Auto-expiry is modeled * as a transition to `expired` and is therefore a legal target from the live states. */ declare const ALLOWED_TRANSITIONS: Readonly>; /** * True when an agent may move from `from` to `to` under the lifecycle rules. * * A transition from a state to itself is never legal here; same-state operations (such as a * credential rotation that preserves status) do not go through this check. * * @param from - Current lifecycle state. * @param to - Proposed next state. * @returns Whether the move is permitted. */ declare function canTransition(from: AgentStatus, to: AgentStatus): boolean; /** * The states an agent can authorize from. Only `active` qualifies; every other state is * fail-closed. Kept as a named predicate so the rule is stated once and reused by the engine, * the edge verifier, and the stats counter. * * @param status - The lifecycle state to test. * @returns Whether an agent in this state may ever authorize an action. */ declare function isAuthorizableStatus(status: AgentStatus): boolean; /** * Whether a state is terminal in the sense that no operator transition other than archival (or, * for expired, renewal) remains. Used by {@link import('../types.js').Krikos.prune} eligibility * checks and dashboards. * * @param status - The lifecycle state to test. * @returns Whether the state is terminal. */ declare function isTerminalStatus(status: AgentStatus): boolean; /** * Key-value state backend of Krikos: one JSON string under one key in any structural * {@link KvLike} store, the persistence shape for edge runtimes and multi-instance hosts that * already run Redis, Upstash, or Cloudflare KV. * * Krikos never constructs the client and never sees connection credentials; the host passes a * ready object. * * @packageDocumentation */ /** * Creates a state backend persisting snapshots as one JSON string in a key-value store. * * Any client exposing string get and set wraps into {@link KvLike} in one line, no adapter * package needed: * * @example * ```ts * // Redis (node-redis or ioredis): * const state = kvState({ get: (k) => redis.get(k), set: (k, v) => redis.set(k, v) }); * * // Upstash Redis: * const state = kvState({ get: (k) => upstash.get(k), set: (k, v) => upstash.set(k, v) }); * * // Cloudflare KV (a binding named KRIKOS_KV): * const state = kvState({ * get: (k) => env.KRIKOS_KV.get(k), * set: (k, v) => env.KRIKOS_KV.put(k, v), * }); * ``` * * Load tolerates both `null` and `undefined` from `get`, the two absence conventions in the * wild, and returns `undefined` for either, the normal first-run case. A present but unparseable * value throws KrikosError `'ERR_STATE_LOAD'`, and a parseable value with the wrong snapshot * version throws KrikosError `'ERR_STATE_VERSION'`. * * @param kv - The ready client, see {@link KvLike}. * @param key - Storage key for the snapshot, namespace it per registry when several share one * store. */ declare function kvState(kv: KvLike, key?: string): StateBackend; /** * In-memory state backend of Krikos: the zero-config default persistence shape, a snapshot held * in a closure variable. Nothing survives the process, which is exactly right for tests, demos, * and hosts that persist elsewhere. * * @packageDocumentation */ /** * Creates a state backend that keeps the latest snapshot in memory. * * Each call returns an independent backend with its own closure variable; two registries given * two `memoryState()` results never see each other's snapshots. The snapshot object is stored by * reference, callers must treat saved snapshots as immutable, which the {@link StateSnapshot} * readonly contract already requires. * * @returns A {@link StateBackend} whose `load` resolves to the last saved snapshot, or * `undefined` before the first save. */ declare function memoryState(): StateBackend; /** * Deterministic, non-cryptographic hashing primitives for Krikos: agent fingerprints (the * content identity of an agent at a credential epoch), audit-chain digests, and seeded short * identifiers. * * Everything here is pure, allocation-light, dependency-free, and runs identically in browsers, * edge runtimes, workers, and Node. No randomness, no clock, no platform globals, so two * processes that canonicalize byte-identical agents derive byte-identical fingerprints. * * Security stance: FNV-1a is NOT a cryptographic hash. It is trivially invertible and * collision-constructible by an adversary, so values produced by this module must never gate a * security decision on their own (authentication, authorization, integrity verification). They * exist to give byte-equal inputs equal keys for agent identity, deduplication, and * tamper-evident audit bookkeeping. Cryptographic agent identity is a separate, opt-in layer: * the Ed25519 signer in `@takk/krikos/a2a`, which signs the fingerprint produced here. * * @packageDocumentation */ /** * Hashes `text` with FNV-1a 64-bit over its UTF-16 code units (two bytes per code unit, low * byte first) and returns the digest as a fixed-width 16-character lowercase hex string. * * Determinism: pure function of the input, identical across runtimes and runs. * * Collision odds, non-adversarial inputs: with a 64-bit digest the birthday bound puts the * probability of any collision among n distinct inputs at roughly n^2 / 2^65, about 1 in 37 * million for one million distinct agents, reaching 50 percent only near 5 billion inputs. * Acceptable for fingerprint bookkeeping, where a collision costs at worst one misattributed * deduplication, never a wrong authorization decision (authorization keys off the agent id and * lifecycle state, not the fingerprint). * * Non-cryptographic: an adversary can construct collisions at will. Never use the result alone * for security decisions, see the module-level security stance. * * @param text - The string to hash, hashed as-is with no normalization. * @returns 16 lowercase hex characters, zero-padded, for example '0a1b2c3d4e5f6789'. */ declare function fnv1a64(text: string): string; /** * Derives one key from several parts by joining them with a separator that cannot appear in hex * output (U+001F) and hashing the joined string with {@link fnv1a64}. * * The separator guarantees that part boundaries contribute to the digest, so * `combineKeys(['ab', 'c'])` and `combineKeys(['a', 'bc'])` differ even though their * concatenations are equal. Krikos uses it to fuse an agent's identity-defining fields into a * stable fingerprint and to chain audit events into a tamper-evident log. * * Same non-cryptographic caveats and collision odds as {@link fnv1a64}. * * @param parts - Key components in significance order, empty parts are preserved. * @returns 16 lowercase hex characters identifying the part sequence. */ declare function combineKeys(parts: readonly string[]): string; export { ALLOWED_TRANSITIONS as A, KrikosError as K, combineKeys as a, createKrikos as b, canTransition as c, isTerminalStatus as d, fnv1a64 as f, isAuthorizableStatus as i, kvState as k, memoryState as m };