@edictum/core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/limits.ts","../src/storage.ts","../src/findings.ts","../src/compiled-state.ts","../src/guard.ts","../src/factory.ts","../src/yaml-engine/composer.ts","../src/yaml-engine/operators.ts","../src/yaml-engine/selectors.ts","../src/yaml-engine/evaluator.ts","../src/yaml-engine/compiler-utils.ts","../src/yaml-engine/compile-contracts.ts","../src/yaml-engine/sandbox-compiler.ts","../src/fnmatch.ts","../src/yaml-engine/sandbox-compile-fn.ts","../src/yaml-engine/compiler.ts","../src/yaml-engine/loader.ts","../src/yaml-engine/loader-validators.ts","../src/index.ts"],"sourcesContent":["/** Operation Limits — tool call and attempt caps. */\n\n/**\n * Operation limits for an agent session.\n *\n * Two counter types:\n * - maxAttempts: caps ALL PreToolUse events (including denied)\n * - maxToolCalls: caps EXECUTIONS only (PostToolUse)\n *\n * Both are checked. Whichever fires first wins.\n */\nexport interface OperationLimits {\n readonly maxAttempts: number;\n readonly maxToolCalls: number;\n readonly maxCallsPerTool: Readonly<Record<string, number>>;\n}\n\nexport const DEFAULT_LIMITS: OperationLimits = Object.freeze({\n maxAttempts: 500,\n maxToolCalls: 200,\n maxCallsPerTool: Object.freeze({}),\n});\n","/** StorageBackend interface + MemoryBackend implementation. */\n\n// ---------------------------------------------------------------------------\n// StorageBackend — protocol for persistent state storage\n// ---------------------------------------------------------------------------\n\n/**\n * Protocol for persistent state storage.\n *\n * Requirements:\n * - increment() MUST be atomic\n * - get/set for simple key-value\n *\n * v0.1.0: No append() method (counters only, no list ops).\n */\nexport interface StorageBackend {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n delete(key: string): Promise<void>;\n increment(key: string, amount?: number): Promise<number>;\n}\n\n// ---------------------------------------------------------------------------\n// MemoryBackend — in-memory implementation for dev/testing\n// ---------------------------------------------------------------------------\n\n/**\n * In-memory storage for development and testing.\n *\n * WARNING: State lost on restart. Session contracts reset.\n * Suitable for: local dev, tests, single-process scripts.\n *\n * Node.js is single-threaded — Map operations are atomic.\n * No lock needed (unlike Python's asyncio.Lock).\n */\nexport class MemoryBackend implements StorageBackend {\n private readonly _data: Map<string, string> = new Map();\n private readonly _counters: Map<string, number> = new Map();\n\n async get(key: string): Promise<string | null> {\n const strVal = this._data.get(key);\n if (strVal !== undefined) {\n return strVal;\n }\n const numVal = this._counters.get(key);\n if (numVal !== undefined) {\n return numVal === Math.trunc(numVal)\n ? String(Math.trunc(numVal))\n : String(numVal);\n }\n return null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this._data.set(key, value);\n }\n\n async delete(key: string): Promise<void> {\n this._data.delete(key);\n this._counters.delete(key);\n }\n\n async increment(key: string, amount: number = 1): Promise<number> {\n const current = this._counters.get(key) ?? 0;\n const next = current + amount;\n this._counters.set(key, next);\n return next;\n }\n\n /**\n * Retrieve multiple values in a single operation.\n *\n * In-memory implementation: multiple Map lookups, no network overhead.\n */\n async batchGet(keys: readonly string[]): Promise<Record<string, string | null>> {\n const result: Record<string, string | null> = {};\n for (const key of keys) {\n result[key] = await this.get(key);\n }\n return result;\n }\n}\n","/** Structured postcondition findings. */\n\n// ---------------------------------------------------------------------------\n// Finding\n// ---------------------------------------------------------------------------\n\n/**\n * A structured finding from a postcondition evaluation.\n *\n * Produced when a postcondition warns or detects an issue.\n * Returned to the caller via PostCallResult so they can\n * decide how to remediate.\n */\nexport interface Finding {\n readonly type: string;\n readonly contractId: string;\n readonly field: string;\n readonly message: string;\n readonly metadata: Readonly<Record<string, unknown>>;\n}\n\n/** Create a frozen Finding with defaults for metadata. */\nexport function createFinding(\n fields: Pick<Finding, \"type\" | \"contractId\" | \"field\" | \"message\"> &\n Partial<Pick<Finding, \"metadata\">>,\n): Finding {\n return Object.freeze({\n type: fields.type,\n contractId: fields.contractId,\n field: fields.field,\n message: fields.message,\n metadata: Object.freeze({ ...(fields.metadata ?? {}) }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// PostCallResult\n// ---------------------------------------------------------------------------\n\n/**\n * Result from a governed tool call, including postcondition findings.\n *\n * Returned by adapter's postToolCall and available via asToolWrapper.\n *\n * When postconditionsPassed is false, the findings list contains\n * structured Finding objects describing what was detected. The caller\n * can then decide how to remediate (redact, replace, log, etc.).\n */\nexport interface PostCallResult {\n readonly result: unknown;\n readonly postconditionsPassed: boolean;\n readonly findings: readonly Finding[];\n readonly outputSuppressed: boolean;\n}\n\n/** Create a PostCallResult with defaults. */\nexport function createPostCallResult(\n fields: Pick<PostCallResult, \"result\"> &\n Partial<Omit<PostCallResult, \"result\">>,\n): PostCallResult {\n return Object.freeze({\n result: fields.result,\n postconditionsPassed: fields.postconditionsPassed ?? true,\n findings: Object.freeze([...(fields.findings ?? [])]),\n outputSuppressed: fields.outputSuppressed ?? false,\n });\n}\n\n// ---------------------------------------------------------------------------\n// classifyFinding\n// ---------------------------------------------------------------------------\n\n/**\n * Classify a postcondition finding type from contract ID and message.\n *\n * Returns a standard finding type string.\n */\nexport function classifyFinding(\n contractId: string,\n verdictMessage: string,\n): string {\n const contractLower = contractId.toLowerCase();\n const messageLower = (verdictMessage || \"\").toLowerCase();\n\n const piiTerms = [\"pii\", \"ssn\", \"patient\", \"name\", \"dob\"];\n if (\n piiTerms.some(\n (term) => contractLower.includes(term) || messageLower.includes(term),\n )\n ) {\n return \"pii_detected\";\n }\n\n const secretTerms = [\"secret\", \"token\", \"key\", \"credential\", \"password\"];\n if (\n secretTerms.some(\n (term) => contractLower.includes(term) || messageLower.includes(term),\n )\n ) {\n return \"secret_detected\";\n }\n\n const limitTerms = [\"session\", \"limit\", \"max_calls\", \"budget\"];\n if (\n limitTerms.some(\n (term) => contractLower.includes(term) || messageLower.includes(term),\n )\n ) {\n return \"limit_exceeded\";\n }\n\n return \"policy_violation\";\n}\n\n// ---------------------------------------------------------------------------\n// PostDecision — structural type (pipeline.ts doesn't exist yet)\n// ---------------------------------------------------------------------------\n\n/**\n * Structural type for the PostDecision fields consumed by buildFindings.\n *\n * The full PostDecision lives in pipeline.ts. This captures only the\n * subset needed here to avoid a circular import.\n */\nexport interface PostDecisionLike {\n readonly contractsEvaluated: ReadonlyArray<{\n readonly passed?: boolean;\n readonly name: string;\n readonly message?: string;\n readonly metadata?: Record<string, unknown>;\n }>;\n}\n\n// ---------------------------------------------------------------------------\n// buildFindings\n// ---------------------------------------------------------------------------\n\n/**\n * Build Finding objects from a PostDecision's failed postconditions.\n *\n * The `field` value is extracted from `metadata.field` if the\n * contract provides it (e.g. `Verdict.fail(\"msg\", { field: \"output.text\" })`),\n * otherwise defaults to `\"output\"` for postconditions.\n */\nexport function buildFindings(postDecision: PostDecisionLike): Finding[] {\n const findings: Finding[] = [];\n for (const cr of postDecision.contractsEvaluated) {\n if (!cr.passed) {\n const meta = cr.metadata ?? {};\n findings.push(\n createFinding({\n type: classifyFinding(cr.name, cr.message ?? \"\"),\n contractId: cr.name,\n field: (meta.field as string) ?? \"output\",\n message: cr.message ?? \"\",\n metadata: meta,\n }),\n );\n }\n }\n return findings;\n}\n","/**\n * _CompiledState -- frozen snapshot of compiled contracts.\n *\n * All contract lists are readonly arrays (frozen). The entire state is\n * replaced atomically via a single reference assignment in reload(),\n * ensuring concurrent evaluations never see a mix of old and new\n * contracts.\n */\n\nimport { deepFreeze } from \"./envelope.js\";\nimport type {\n InternalPrecondition,\n InternalPostcondition,\n InternalSessionContract,\n InternalSandboxContract,\n} from \"./internal-contracts.js\";\nimport { DEFAULT_LIMITS } from \"./limits.js\";\nimport type { OperationLimits } from \"./limits.js\";\n\nexport interface CompiledState {\n readonly preconditions: readonly InternalPrecondition[];\n readonly postconditions: readonly InternalPostcondition[];\n readonly sessionContracts: readonly InternalSessionContract[];\n readonly sandboxContracts: readonly InternalSandboxContract[];\n readonly observePreconditions: readonly InternalPrecondition[];\n readonly observePostconditions: readonly InternalPostcondition[];\n readonly observeSessionContracts: readonly InternalSessionContract[];\n readonly observeSandboxContracts: readonly InternalSandboxContract[];\n readonly limits: OperationLimits;\n readonly policyVersion: string | null;\n}\n\nexport function createCompiledState(\n partial: Partial<CompiledState> = {},\n): CompiledState {\n return deepFreeze({\n preconditions: partial.preconditions ?? [],\n postconditions: partial.postconditions ?? [],\n sessionContracts: partial.sessionContracts ?? [],\n sandboxContracts: partial.sandboxContracts ?? [],\n observePreconditions: partial.observePreconditions ?? [],\n observePostconditions: partial.observePostconditions ?? [],\n observeSessionContracts: partial.observeSessionContracts ?? [],\n observeSandboxContracts: partial.observeSandboxContracts ?? [],\n limits: partial.limits ?? DEFAULT_LIMITS,\n policyVersion: partial.policyVersion ?? null,\n });\n}\n","/**\n * Core Edictum class -- construction, contract registry, and accessor methods.\n *\n * SIZE APPROVAL: This file exceeds 200 lines. It mirrors Python's _guard.py\n * (314 LOC) which is already the decomposed version of the original god class.\n * The contract classification + accessor methods form a cohesive unit.\n *\n * Minimum viable guard: constructor + contract classification + accessors.\n * run(), from_yaml(), from_server() are delegated methods added later.\n */\n\nimport { randomUUID } from \"node:crypto\";\n\nimport type { ApprovalBackend } from \"./approval.js\";\nimport {\n fromYaml as _fromYaml,\n fromYamlString as _fromYamlString,\n reload as _reload,\n} from \"./factory.js\";\nimport type { FromYamlOptions, ReloadOptions, YamlFactoryOptions } from \"./factory.js\";\nimport type { CompositionReport } from \"./yaml-engine/composer.js\";\nimport { CollectingAuditSink, CompositeSink } from \"./audit.js\";\nimport type { AuditSink } from \"./audit.js\";\nimport { createCompiledState } from \"./compiled-state.js\";\nimport { EdictumConfigError } from \"./errors.js\";\nimport type { CompiledState } from \"./compiled-state.js\";\nimport type {\n Precondition,\n Postcondition,\n SessionContract,\n} from \"./contracts.js\";\nimport { SideEffect, ToolRegistry } from \"./envelope.js\";\nimport type { Principal, ToolEnvelope } from \"./envelope.js\";\nimport type { EvaluationResult } from \"./evaluation.js\";\nimport { fnmatch } from \"./fnmatch.js\";\nimport type {\n GuardLike,\n InternalPrecondition,\n InternalPostcondition,\n InternalSessionContract,\n InternalSandboxContract,\n} from \"./internal-contracts.js\";\nimport { DEFAULT_LIMITS } from \"./limits.js\";\nimport type { OperationLimits } from \"./limits.js\";\nimport { RedactionPolicy } from \"./redaction.js\";\nimport { MemoryBackend } from \"./storage.js\";\nimport type { StorageBackend } from \"./storage.js\";\nimport type { HookRegistration } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// User contract type discrimination\n// ---------------------------------------------------------------------------\n\n/** User-facing contract with optional name (not in interface, but allowed). */\ntype NamedContract = { readonly name?: string };\n\nfunction isSessionContract(\n c: Precondition | Postcondition | SessionContract,\n): c is SessionContract {\n return !(\"tool\" in c);\n}\n\n// ---------------------------------------------------------------------------\n// EdictumOptions\n// ---------------------------------------------------------------------------\n\n/** Constructor options for the Edictum guard. */\nexport interface EdictumOptions {\n readonly environment?: string;\n readonly mode?: \"enforce\" | \"observe\";\n readonly limits?: OperationLimits;\n readonly tools?: Record<\n string,\n { side_effect?: string; idempotent?: boolean }\n >;\n readonly contracts?: ReadonlyArray<\n Precondition | Postcondition | SessionContract\n >;\n readonly hooks?: ReadonlyArray<HookRegistration>;\n readonly auditSink?: AuditSink | AuditSink[];\n readonly redaction?: RedactionPolicy;\n readonly backend?: StorageBackend;\n readonly policyVersion?: string;\n readonly onDeny?: (\n envelope: ToolEnvelope,\n reason: string,\n source: string | null,\n ) => void;\n readonly onAllow?: (envelope: ToolEnvelope) => void;\n readonly successCheck?: (toolName: string, result: unknown) => boolean;\n readonly principal?: Principal;\n readonly principalResolver?: (\n toolName: string,\n toolInput: Record<string, unknown>,\n ) => Principal;\n readonly approvalBackend?: ApprovalBackend;\n}\n\n// ---------------------------------------------------------------------------\n// Edictum class\n// ---------------------------------------------------------------------------\n\n/**\n * Main configuration and entrypoint.\n *\n * Two usage modes:\n * 1. With framework adapter: use the appropriate adapter\n * 2. Framework-agnostic: use guard.run() directly\n */\nexport class Edictum implements GuardLike {\n readonly environment: string;\n readonly mode: \"enforce\" | \"observe\";\n readonly backend: StorageBackend;\n readonly redaction: RedactionPolicy;\n readonly toolRegistry: ToolRegistry;\n readonly auditSink: AuditSink;\n\n private readonly _localSink: CollectingAuditSink;\n private _state: CompiledState;\n private readonly _beforeHooks: HookRegistration[];\n private readonly _afterHooks: HookRegistration[];\n private readonly _sessionId: string;\n\n // Callbacks and resolution — not private because _runner.ts needs access\n // (Python's _runner.py accesses self._on_deny etc. directly)\n /** @internal */ readonly _onDeny:\n | ((\n envelope: ToolEnvelope,\n reason: string,\n source: string | null,\n ) => void)\n | null;\n /** @internal */ readonly _onAllow: ((envelope: ToolEnvelope) => void) | null;\n /** @internal */ readonly _successCheck:\n | ((toolName: string, result: unknown) => boolean)\n | null;\n private _principal: Principal | null;\n private readonly _principalResolver:\n | ((\n toolName: string,\n toolInput: Record<string, unknown>,\n ) => Principal)\n | null;\n /** @internal */ readonly _approvalBackend: ApprovalBackend | null;\n\n constructor(options: EdictumOptions = {}) {\n this.environment = options.environment ?? \"production\";\n this.mode = options.mode ?? \"enforce\";\n this.backend = options.backend ?? new MemoryBackend();\n this.redaction = options.redaction ?? new RedactionPolicy();\n this._onDeny = options.onDeny ?? null;\n this._onAllow = options.onAllow ?? null;\n this._successCheck = options.successCheck ?? null;\n this._principal = options.principal ?? null;\n this._principalResolver = options.principalResolver ?? null;\n this._approvalBackend = options.approvalBackend ?? null;\n\n // Audit sink: local sink always present\n this._localSink = new CollectingAuditSink();\n if (Array.isArray(options.auditSink)) {\n this.auditSink = new CompositeSink([\n this._localSink,\n ...options.auditSink,\n ]);\n } else if (options.auditSink != null) {\n this.auditSink = new CompositeSink([\n this._localSink,\n options.auditSink,\n ]);\n } else {\n this.auditSink = this._localSink;\n }\n\n // Build tool registry\n this.toolRegistry = new ToolRegistry();\n if (options.tools) {\n for (const [name, config] of Object.entries(options.tools)) {\n this.toolRegistry.register(\n name,\n (config.side_effect as SideEffect | undefined) ??\n SideEffect.IRREVERSIBLE,\n config.idempotent ?? false,\n );\n }\n }\n\n // Classify contracts and build compiled state\n this._state = Edictum._classifyContracts(\n options.contracts ?? [],\n options.limits ?? DEFAULT_LIMITS,\n options.policyVersion ?? null,\n );\n\n // Hooks are not reloaded -- mutable lists are fine\n this._beforeHooks = [];\n this._afterHooks = [];\n for (const item of options.hooks ?? []) {\n this._registerHook(item);\n }\n\n // Persistent session ID for accumulating limits across run() calls\n this._sessionId = randomUUID();\n }\n\n // -----------------------------------------------------------------------\n // Properties\n // -----------------------------------------------------------------------\n\n /** The local in-memory audit event collector. Always present. */\n get localSink(): CollectingAuditSink {\n return this._localSink;\n }\n\n /** Operation limits for the current contract set. */\n get limits(): OperationLimits {\n return this._state.limits;\n }\n\n /** Update operation limits (replaces compiled state atomically). */\n set limits(value: OperationLimits) {\n this._state = createCompiledState({ ...this._state, limits: value });\n }\n\n /** SHA256 hash identifying the active contract bundle. */\n get policyVersion(): string | null {\n return this._state.policyVersion;\n }\n\n /**\n * Replace the compiled state atomically.\n *\n * @internal — used by factory.ts reload(). Not part of the public API.\n */\n _replaceState(newState: CompiledState): void {\n this._state = newState;\n }\n\n /**\n * Read the current compiled state.\n *\n * @internal — used by factory.ts reload(). Not part of the public API.\n */\n _getState(): CompiledState {\n return this._state;\n }\n\n /** Update policy version (replaces compiled state atomically). */\n set policyVersion(value: string | null) {\n this._state = createCompiledState({\n ...this._state,\n policyVersion: value,\n });\n }\n\n /** The persistent session ID for this guard instance. */\n get sessionId(): string {\n return this._sessionId;\n }\n\n // -----------------------------------------------------------------------\n // Principal\n // -----------------------------------------------------------------------\n\n /** Update the principal used for subsequent tool calls. */\n setPrincipal(principal: Principal): void {\n this._principal = principal;\n }\n\n /** Resolve the principal for a tool call. */\n _resolvePrincipal(\n toolName: string,\n toolInput: Record<string, unknown>,\n ): Principal | null {\n if (this._principalResolver != null) {\n return this._principalResolver(toolName, toolInput);\n }\n return this._principal;\n }\n\n // -----------------------------------------------------------------------\n // Hooks\n // -----------------------------------------------------------------------\n\n private _registerHook(item: HookRegistration): void {\n if (item.phase === \"before\") {\n this._beforeHooks.push(item);\n } else {\n this._afterHooks.push(item);\n }\n }\n\n getHooks(\n phase: \"before\" | \"after\",\n envelope: ToolEnvelope,\n ): HookRegistration[] {\n const hooks =\n phase === \"before\" ? this._beforeHooks : this._afterHooks;\n return hooks.filter(\n (h) => h.tool === \"*\" || fnmatch(envelope.toolName, h.tool),\n );\n }\n\n // -----------------------------------------------------------------------\n // Contract accessors -- enforce mode\n // -----------------------------------------------------------------------\n\n getPreconditions(envelope: ToolEnvelope): InternalPrecondition[] {\n return Edictum._filterByTool(\n this._state.preconditions as InternalPrecondition[],\n envelope,\n );\n }\n\n getPostconditions(envelope: ToolEnvelope): InternalPostcondition[] {\n return Edictum._filterByTool(\n this._state.postconditions as InternalPostcondition[],\n envelope,\n );\n }\n\n getSessionContracts(): InternalSessionContract[] {\n return [...this._state.sessionContracts];\n }\n\n getSandboxContracts(envelope: ToolEnvelope): InternalSandboxContract[] {\n return Edictum._filterSandbox(\n this._state.sandboxContracts as InternalSandboxContract[],\n envelope,\n );\n }\n\n // -----------------------------------------------------------------------\n // Contract accessors -- observe mode\n // -----------------------------------------------------------------------\n\n getObservePreconditions(\n envelope: ToolEnvelope,\n ): InternalPrecondition[] {\n return Edictum._filterByTool(\n this._state.observePreconditions as InternalPrecondition[],\n envelope,\n );\n }\n\n getObservePostconditions(\n envelope: ToolEnvelope,\n ): InternalPostcondition[] {\n return Edictum._filterByTool(\n this._state.observePostconditions as InternalPostcondition[],\n envelope,\n );\n }\n\n getObserveSessionContracts(): InternalSessionContract[] {\n return [...this._state.observeSessionContracts];\n }\n\n getObserveSandboxContracts(\n envelope: ToolEnvelope,\n ): InternalSandboxContract[] {\n return Edictum._filterSandbox(\n this._state.observeSandboxContracts as InternalSandboxContract[],\n envelope,\n );\n }\n\n // -----------------------------------------------------------------------\n // Private helpers\n // -----------------------------------------------------------------------\n\n /**\n * Classify user-facing and internal contracts into enforce/observe lists.\n *\n * User-facing contracts (Precondition, Postcondition, SessionContract)\n * are converted to internal representations. Internal contracts (from\n * YAML compiler) carry _edictum_* metadata and are classified by their\n * _edictum_observe flag (Python uses _edictum_shadow — wire-format parity).\n */\n private static _classifyContracts(\n contracts: ReadonlyArray<\n Precondition | Postcondition | SessionContract\n >,\n limits: OperationLimits,\n policyVersion: string | null,\n ): CompiledState {\n const pre: InternalPrecondition[] = [];\n const post: InternalPostcondition[] = [];\n const session: InternalSessionContract[] = [];\n const sandbox: InternalSandboxContract[] = [];\n const oPre: InternalPrecondition[] = [];\n const oPost: InternalPostcondition[] = [];\n const oSession: InternalSessionContract[] = [];\n const oSandbox: InternalSandboxContract[] = [];\n\n for (const item of contracts) {\n const raw = item as unknown as Record<string, unknown>;\n const edictumType = raw._edictum_type as string | undefined;\n // Python YAML compiler emits _edictum_shadow; we accept both for wire-format parity\n const isObserve =\n (raw._edictum_observe as boolean) ??\n (raw._edictum_shadow as boolean) ??\n false;\n\n if (edictumType != null) {\n // Internal contract (from YAML compiler)\n Edictum._classifyInternal(\n raw,\n edictumType,\n isObserve,\n { pre, post, session, sandbox, oPre, oPost, oSession, oSandbox },\n );\n } else if (isSessionContract(item)) {\n const name = (raw as NamedContract).name ?? \"anonymous\";\n session.push({\n type: \"session_contract\",\n name,\n check: (item as SessionContract).check,\n });\n } else if (\"tool\" in item && (item as { contractType?: string }).contractType === \"post\") {\n const postItem = item as Postcondition;\n const name = (raw as NamedContract).name ?? \"anonymous\";\n post.push({\n type: \"postcondition\",\n name,\n tool: postItem.tool,\n check: postItem.check,\n when: postItem.when,\n });\n } else if (\"tool\" in item) {\n // Fail-closed: reject unknown contractType and detect missing \"post\"\n const ct = (raw as { contractType?: unknown }).contractType;\n if (ct != null && ct !== \"pre\") {\n throw new EdictumConfigError(\n `Contract with tool \"${(item as Precondition).tool}\" has unknown contractType ` +\n `\"${String(ct)}\". Expected \"pre\" or omitted for Precondition, \"post\" for Postcondition.`,\n );\n }\n // Best-effort heuristic for JS consumers who forget contractType: \"post\".\n // NOTE: Function.length is unreliable for rest parameters (...args) and\n // default-valued params — both give length 0. This catches the common\n // case (explicit (envelope, output)) but cannot guarantee detection.\n // Always set contractType: \"post\" explicitly.\n if (ct == null && item.check.length >= 2) {\n throw new EdictumConfigError(\n `Contract with tool \"${(item as Precondition).tool}\" has a check function with ` +\n `${item.check.length} parameters (looks like a Postcondition) but is missing ` +\n `contractType: \"post\". Add it to prevent misclassification.`,\n );\n }\n const preItem = item as Precondition;\n const name = (raw as NamedContract).name ?? \"anonymous\";\n pre.push({\n type: \"precondition\",\n name,\n tool: preItem.tool,\n check: preItem.check,\n when: preItem.when,\n });\n }\n }\n\n return createCompiledState({\n preconditions: pre,\n postconditions: post,\n sessionContracts: session,\n sandboxContracts: sandbox,\n observePreconditions: oPre,\n observePostconditions: oPost,\n observeSessionContracts: oSession,\n observeSandboxContracts: oSandbox,\n limits,\n policyVersion,\n });\n }\n\n /** Route an internal contract to the appropriate enforce/observe list. */\n private static _classifyInternal(\n raw: Record<string, unknown>,\n edictumType: string,\n isObserve: boolean,\n lists: {\n pre: InternalPrecondition[];\n post: InternalPostcondition[];\n session: InternalSessionContract[];\n sandbox: InternalSandboxContract[];\n oPre: InternalPrecondition[];\n oPost: InternalPostcondition[];\n oSession: InternalSessionContract[];\n oSandbox: InternalSandboxContract[];\n },\n ): void {\n const target = isObserve\n ? { pre: lists.oPre, post: lists.oPost, session: lists.oSession, sandbox: lists.oSandbox }\n : { pre: lists.pre, post: lists.post, session: lists.session, sandbox: lists.sandbox };\n\n if (edictumType === \"precondition\") target.pre.push(raw as unknown as InternalPrecondition);\n else if (edictumType === \"postcondition\") target.post.push(raw as unknown as InternalPostcondition);\n else if (edictumType === \"session_contract\") target.session.push(raw as unknown as InternalSessionContract);\n else if (edictumType === \"sandbox\") target.sandbox.push(raw as unknown as InternalSandboxContract);\n else {\n throw new EdictumConfigError(\n `Unknown _edictum_type \"${edictumType}\". ` +\n `Expected \"precondition\", \"postcondition\", \"session_contract\", or \"sandbox\".`,\n );\n }\n }\n\n /** Filter contracts by tool pattern and optional `when` guard. */\n private static _filterByTool<\n T extends {\n readonly tool: string;\n readonly when?: ((envelope: ToolEnvelope) => boolean) | null;\n },\n >(contracts: T[], envelope: ToolEnvelope): T[] {\n const result: T[] = [];\n for (const p of contracts) {\n const tool = p.tool ?? \"*\";\n const when = p.when ?? null;\n if (tool !== \"*\" && !fnmatch(envelope.toolName, tool)) {\n continue;\n }\n if (when != null) {\n try {\n if (!when(envelope)) continue;\n } catch {\n // Fail-closed: throwing predicate includes the contract (not excludes)\n // so it gets evaluated and can deny — safer than silently skipping.\n }\n }\n result.push(p);\n }\n return result;\n }\n\n /** Filter sandbox contracts by tool patterns array. */\n private static _filterSandbox(\n contracts: InternalSandboxContract[],\n envelope: ToolEnvelope,\n ): InternalSandboxContract[] {\n const result: InternalSandboxContract[] = [];\n for (const s of contracts) {\n const tools = s.tools ?? [\"*\"];\n if (tools.some((p) => fnmatch(envelope.toolName, p))) {\n result.push(s);\n }\n }\n return result;\n }\n\n // -----------------------------------------------------------------------\n // Delegated methods — run, evaluate, evaluateBatch\n // -----------------------------------------------------------------------\n\n /** Execute a tool call with full governance pipeline. */\n async run(\n toolName: string,\n args: Record<string, unknown>,\n toolCallable: (\n args: Record<string, unknown>,\n ) => unknown | Promise<unknown>,\n options?: {\n sessionId?: string;\n environment?: string;\n principal?: Principal;\n },\n ): Promise<unknown> {\n const { run } = await import(\"./runner.js\");\n return run(this, toolName, args, toolCallable, options);\n }\n\n /**\n * Dry-run evaluation of a tool call against all matching contracts.\n *\n * Never executes the tool. Evaluates exhaustively (no short-circuit).\n * Session contracts are skipped.\n */\n evaluate(\n toolName: string,\n args: Record<string, unknown>,\n options?: {\n principal?: Principal;\n output?: string;\n environment?: string;\n },\n ): Promise<EvaluationResult> {\n // Dynamic import avoids circular dependency\n return import(\"./dry-run.js\").then(({ evaluate }) =>\n evaluate(this, toolName, args, options),\n );\n }\n\n /** Evaluate a batch of tool calls. Thin wrapper over evaluate(). */\n evaluateBatch(\n calls: Array<{\n tool: string;\n args?: Record<string, unknown>;\n principal?: Record<string, unknown>;\n output?: string | Record<string, unknown>;\n environment?: string;\n }>,\n ): Promise<EvaluationResult[]> {\n return import(\"./dry-run.js\").then(({ evaluateBatch }) =>\n evaluateBatch(this, calls),\n );\n }\n\n // -----------------------------------------------------------------------\n // YAML factory methods — delegate to factory.ts\n // Circular dependency (factory.ts imports guard.ts) is safe because\n // ESM resolves all bindings before user code calls these methods.\n // -----------------------------------------------------------------------\n\n /**\n * Create an Edictum instance from one or more YAML contract bundle paths.\n *\n * When multiple paths are given, bundles are composed left-to-right\n * (later layers override earlier ones).\n *\n * When the trailing options object has `returnReport: true`, returns\n * a tuple of [Edictum, CompositionReport].\n */\n static fromYaml(\n ...args: [...string[], FromYamlOptions & { returnReport: true }]\n ): [Edictum, CompositionReport];\n static fromYaml(\n ...args: [...string[], FromYamlOptions] | string[]\n ): Edictum;\n static fromYaml(\n ...args: [...string[], FromYamlOptions] | string[]\n ): Edictum | [Edictum, CompositionReport] {\n return _fromYaml(...args);\n }\n\n /**\n * Create an Edictum instance from a YAML string or Uint8Array.\n */\n static fromYamlString(\n content: string | Uint8Array,\n options?: YamlFactoryOptions,\n ): Edictum {\n return _fromYamlString(content, options);\n }\n\n /**\n * Atomically replace this guard's contracts from a YAML string.\n *\n * Pass customOperators/customSelectors if the new YAML uses custom\n * operators or selectors that were passed to fromYaml/fromYamlString.\n */\n reload(yamlContent: string, options?: ReloadOptions): void {\n _reload(this, yamlContent, options);\n }\n}\n","/**\n * Factory functions for creating Edictum instances from YAML bundles.\n *\n * Ports Python's _factory.py: fromYaml, fromYamlString, reload.\n *\n * SIZE APPROVAL: This file exceeds 200 lines. It mirrors Python's _factory.py\n * (384 LOC). The three factory functions share option types and helper logic\n * that would create unnecessary coupling if split.\n *\n * Guard.ts delegates to these via dynamic import to avoid circular deps.\n */\n\nimport { createHash } from \"node:crypto\";\n\nimport type { ApprovalBackend } from \"./approval.js\";\nimport type { AuditSink } from \"./audit.js\";\nimport { EdictumConfigError } from \"./errors.js\";\nimport type { Principal, ToolEnvelope } from \"./envelope.js\";\nimport { Edictum } from \"./guard.js\";\nimport type { OperationLimits } from \"./limits.js\";\nimport type { RedactionPolicy } from \"./redaction.js\";\nimport type { StorageBackend } from \"./storage.js\";\nimport { composeBundles } from \"./yaml-engine/composer.js\";\nimport type { CompositionReport } from \"./yaml-engine/composer.js\";\nimport { compileContracts } from \"./yaml-engine/compiler.js\";\nimport type { CustomOperator, CustomSelector } from \"./yaml-engine/evaluator.js\";\nimport { loadBundle, loadBundleString } from \"./yaml-engine/loader.js\";\n\n// ---------------------------------------------------------------------------\n// Shared options type\n// ---------------------------------------------------------------------------\n\n/** Options shared by fromYaml and fromYamlString. */\nexport interface YamlFactoryOptions {\n readonly mode?: \"enforce\" | \"observe\";\n readonly tools?: Record<string, { side_effect?: string; idempotent?: boolean }>;\n readonly auditSink?: AuditSink | AuditSink[];\n readonly redaction?: RedactionPolicy;\n readonly backend?: StorageBackend;\n readonly environment?: string;\n readonly onDeny?: (envelope: ToolEnvelope, reason: string, source: string | null) => void;\n readonly onAllow?: (envelope: ToolEnvelope) => void;\n readonly customOperators?: Record<string, CustomOperator>;\n readonly customSelectors?: Record<string, CustomSelector>;\n readonly successCheck?: (toolName: string, result: unknown) => boolean;\n readonly principal?: Principal;\n readonly principalResolver?: (toolName: string, toolInput: Record<string, unknown>) => Principal;\n readonly approvalBackend?: ApprovalBackend;\n}\n\n/** Options for fromYaml, extending base with returnReport. */\nexport interface FromYamlOptions extends YamlFactoryOptions {\n readonly returnReport?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// fromYaml\n// ---------------------------------------------------------------------------\n\n/**\n * Create an Edictum instance from one or more YAML contract bundle paths.\n *\n * When multiple paths are given, bundles are composed left-to-right\n * (later layers override earlier ones).\n *\n * EXCEPTION TO \"ALL ASYNC\" RULE: This factory is intentionally synchronous,\n * matching Python's from_yaml(). File I/O uses Node's readFileSync and YAML\n * parsing is CPU-bound — neither benefits from async. The returned Edictum\n * instance's run()/evaluate()/evaluateBatch() methods are fully async.\n * Making this async would force all callers to await at module init time\n * for no concurrency benefit.\n */\nexport function fromYaml(\n ...args: [...string[], FromYamlOptions] | string[]\n): Edictum | [Edictum, CompositionReport] {\n // Separate paths from trailing options object\n let paths: string[];\n let options: FromYamlOptions;\n\n const last = args[args.length - 1];\n if (typeof last === \"object\" && last !== null && !Array.isArray(last)) {\n paths = args.slice(0, -1) as string[];\n options = last as FromYamlOptions;\n } else {\n paths = args as string[];\n options = {};\n }\n\n if (paths.length === 0) {\n throw new EdictumConfigError(\"fromYaml() requires at least one path\");\n }\n\n // Load all bundles\n const loaded: [Record<string, unknown>, { hex: string }][] = [];\n for (const p of paths) {\n loaded.push(loadBundle(p));\n }\n\n let bundleData: Record<string, unknown>;\n let policyVersion: string;\n let report: CompositionReport;\n\n if (loaded.length === 1) {\n const entry = loaded[0] as [Record<string, unknown>, { hex: string }];\n bundleData = entry[0];\n policyVersion = entry[1].hex;\n report = { overriddenContracts: [], observeContracts: [] };\n } else {\n const bundleTuples: [Record<string, unknown>, string][] = loaded.map(\n ([data], i) => [data, paths[i] as string],\n );\n const composed = composeBundles(...bundleTuples);\n bundleData = composed.bundle;\n report = composed.report;\n policyVersion = createHash(\"sha256\")\n .update(loaded.map(([, h]) => h.hex).join(\":\"))\n .digest(\"hex\");\n }\n\n const compiled = compileContracts(bundleData, {\n customOperators: options.customOperators ?? null,\n customSelectors: options.customSelectors ?? null,\n });\n\n const guard = _buildGuard(compiled, policyVersion, options);\n\n if (options.returnReport) {\n return [guard, report];\n }\n return guard;\n}\n\n// ---------------------------------------------------------------------------\n// fromYamlString\n// ---------------------------------------------------------------------------\n\n/**\n * Create an Edictum instance from a YAML string or Uint8Array.\n *\n * Like fromYaml but accepts YAML content directly instead of a file path.\n *\n * EXCEPTION TO \"ALL ASYNC\" RULE: Synchronous by design — see fromYaml docs.\n */\nexport function fromYamlString(\n content: string | Uint8Array,\n options: YamlFactoryOptions = {},\n): Edictum {\n const [bundleData, bundleHash] = loadBundleString(content);\n const policyVersion = bundleHash.hex;\n\n const compiled = compileContracts(bundleData, {\n customOperators: options.customOperators ?? null,\n customSelectors: options.customSelectors ?? null,\n });\n\n return _buildGuard(compiled, policyVersion, options);\n}\n\n// ---------------------------------------------------------------------------\n// reload\n// ---------------------------------------------------------------------------\n\n/** Options for reload(). */\nexport interface ReloadOptions {\n readonly customOperators?: Record<string, CustomOperator>;\n readonly customSelectors?: Record<string, CustomSelector>;\n}\n\n/**\n * Atomically replace a guard's contracts from a YAML string.\n *\n * Builds a new CompiledState from the YAML content and swaps the\n * guard's internal state reference. Concurrent evaluations that\n * started before reload() see the old state; evaluations after\n * see the new state.\n */\nexport function reload(\n guard: Edictum,\n yamlContent: string,\n options: ReloadOptions = {},\n): void {\n const [bundleData, bundleHash] = loadBundleString(yamlContent);\n const compiled = compileContracts(bundleData, {\n customOperators: options.customOperators ?? null,\n customSelectors: options.customSelectors ?? null,\n });\n\n const allContracts = [\n ...compiled.preconditions,\n ...compiled.postconditions,\n ...compiled.sessionContracts,\n ...compiled.sandboxContracts,\n ] as unknown[];\n\n // Classify into enforce/observe lists via the same logic the constructor uses.\n // We build a temporary Edictum to leverage _classifyContracts, then steal its state.\n const temp = new Edictum({\n contracts: allContracts as never[],\n limits: compiled.limits,\n policyVersion: bundleHash.hex,\n });\n\n // Atomic state swap via package-internal methods\n guard._replaceState(temp._getState());\n}\n\n// ---------------------------------------------------------------------------\n// Internal: build guard from compiled bundle\n// ---------------------------------------------------------------------------\n\nfunction _buildGuard(\n compiled: {\n preconditions: readonly unknown[];\n postconditions: readonly unknown[];\n sessionContracts: readonly unknown[];\n sandboxContracts: readonly unknown[];\n limits: OperationLimits;\n defaultMode: string;\n tools: Readonly<Record<string, Record<string, unknown>>>;\n },\n policyVersion: string,\n options: YamlFactoryOptions,\n): Edictum {\n const effectiveMode = options.mode ?? compiled.defaultMode;\n\n const allContracts = [\n ...compiled.preconditions,\n ...compiled.postconditions,\n ...compiled.sessionContracts,\n ...compiled.sandboxContracts,\n ];\n\n // Merge YAML tools with parameter tools (parameter wins on conflict)\n const mergedTools: Record<string, { side_effect?: string; idempotent?: boolean }> = {};\n for (const [name, cfg] of Object.entries(compiled.tools)) {\n mergedTools[name] = cfg as { side_effect?: string; idempotent?: boolean };\n }\n if (options.tools) {\n for (const [name, cfg] of Object.entries(options.tools)) {\n mergedTools[name] = cfg;\n }\n }\n\n return new Edictum({\n environment: options.environment ?? \"production\",\n mode: effectiveMode as \"enforce\" | \"observe\",\n limits: compiled.limits,\n tools: Object.keys(mergedTools).length > 0 ? mergedTools : undefined,\n contracts: allContracts as never[],\n auditSink: options.auditSink,\n redaction: options.redaction,\n backend: options.backend,\n policyVersion,\n onDeny: options.onDeny,\n onAllow: options.onAllow,\n successCheck: options.successCheck,\n principal: options.principal,\n principalResolver: options.principalResolver,\n approvalBackend: options.approvalBackend,\n });\n}\n","/** Bundle Composer — merge multiple parsed YAML bundles into one. */\n\nimport { EdictumConfigError } from \"../errors.js\";\n\n/** Records a contract that was replaced during composition. */\nexport interface CompositionOverride {\n readonly contractId: string;\n readonly overriddenBy: string;\n readonly originalSource: string;\n}\n\n/** Records a contract added as an observe-mode copy (observe_alongside). */\nexport interface ObserveContract {\n readonly contractId: string;\n readonly enforcedSource: string;\n readonly observedSource: string;\n}\n\n/** Report of what happened during composition. */\nexport interface CompositionReport {\n readonly overriddenContracts: readonly CompositionOverride[];\n readonly observeContracts: readonly ObserveContract[];\n}\n\n/** Result of composing multiple bundles. */\nexport interface ComposedBundle {\n readonly bundle: Record<string, unknown>;\n readonly report: CompositionReport;\n}\n\nfunction deepCopyBundle(data: Record<string, unknown>): Record<string, unknown> {\n return structuredClone(data);\n}\n\n/**\n * Merge multiple parsed bundle dicts left to right.\n *\n * Each entry is a tuple of [bundleData, sourceLabel]. Later layers\n * have higher priority.\n */\nexport function composeBundles(\n ...bundles: [Record<string, unknown>, string][]\n): ComposedBundle {\n if (bundles.length === 0) {\n throw new Error(\"composeBundles() requires at least one bundle\");\n }\n\n if (bundles.length === 1) {\n const entry = bundles[0] as [Record<string, unknown>, string];\n return {\n bundle: deepCopyBundle(entry[0]),\n report: { overriddenContracts: [], observeContracts: [] },\n };\n }\n\n const overrides: CompositionOverride[] = [];\n const observes: ObserveContract[] = [];\n\n const first = bundles[0] as [Record<string, unknown>, string];\n const merged = deepCopyBundle(first[0]);\n const firstLabel = first[1];\n\n const contractSources = new Map<string, string>();\n for (const c of (merged.contracts ?? []) as Record<string, unknown>[]) {\n contractSources.set(c.id as string, firstLabel);\n }\n\n for (let i = 1; i < bundles.length; i++) {\n const entry = bundles[i] as [Record<string, unknown>, string];\n const [data, label] = entry;\n const isObserveAlongside = Boolean(data.observe_alongside);\n\n if (isObserveAlongside) {\n mergeObserveAlongside(merged, data, label, contractSources, observes);\n } else {\n mergeStandard(merged, data, label, contractSources, overrides);\n }\n }\n\n return {\n bundle: merged,\n report: { overriddenContracts: overrides, observeContracts: observes },\n };\n}\n\nfunction mergeStandard(\n merged: Record<string, unknown>,\n layer: Record<string, unknown>,\n label: string,\n contractSources: Map<string, string>,\n overrides: CompositionOverride[],\n): void {\n if (\"defaults\" in layer) {\n const ld = layer.defaults as Record<string, unknown>;\n const md = (merged.defaults ?? {}) as Record<string, unknown>;\n if (\"mode\" in ld) md.mode = ld.mode;\n if (\"environment\" in ld) md.environment = ld.environment;\n merged.defaults = md;\n }\n\n if (\"limits\" in layer) merged.limits = deepCopyBundle(layer.limits as Record<string, unknown>);\n\n if (\"tools\" in layer) {\n const mt = (merged.tools ?? {}) as Record<string, unknown>;\n for (const [name, cfg] of Object.entries(layer.tools as Record<string, unknown>)) {\n mt[name] = { ...(cfg as Record<string, unknown>) };\n }\n merged.tools = mt;\n }\n\n if (\"metadata\" in layer) {\n const mm = (merged.metadata ?? {}) as Record<string, unknown>;\n for (const [k, v] of Object.entries(layer.metadata as Record<string, unknown>)) mm[k] = v;\n merged.metadata = mm;\n }\n\n if (\"observability\" in layer) {\n merged.observability = deepCopyBundle(layer.observability as Record<string, unknown>);\n }\n\n if (\"contracts\" in layer) {\n const existingById = new Map<string, number>();\n const mc = (merged.contracts ?? []) as Record<string, unknown>[];\n for (let j = 0; j < mc.length; j++) {\n const c = mc[j] as Record<string, unknown>;\n existingById.set(c.id as string, j);\n }\n\n for (const contract of (layer.contracts ?? []) as Record<string, unknown>[]) {\n const cid = contract.id as string;\n const newContract = deepCopyBundle(contract);\n\n if (existingById.has(cid)) {\n const idx = existingById.get(cid) as number;\n overrides.push({\n contractId: cid,\n overriddenBy: label,\n originalSource: contractSources.get(cid) ?? \"unknown\",\n });\n mc[idx] = newContract;\n } else {\n mc.push(newContract);\n existingById.set(cid, mc.length - 1);\n }\n contractSources.set(cid, label);\n }\n merged.contracts = mc;\n }\n}\n\nfunction mergeObserveAlongside(\n merged: Record<string, unknown>,\n layer: Record<string, unknown>,\n label: string,\n contractSources: Map<string, string>,\n observes: ObserveContract[],\n): void {\n const mc = (merged.contracts ?? []) as Record<string, unknown>[];\n\n for (const contract of (layer.contracts ?? []) as Record<string, unknown>[]) {\n const cid = contract.id as string;\n const observeId = `${cid}:candidate`;\n\n // Check for ID collisions — the generated observe ID must not clash\n // with any existing contract in the merged bundle.\n const existingIds = new Set(\n (mc as Record<string, unknown>[]).map((c) => c.id as string),\n );\n if (existingIds.has(observeId)) {\n throw new EdictumConfigError(\n `observe_alongside collision: generated ID \"${observeId}\" already exists in the bundle. ` +\n `Rename the conflicting contract or use a different ID for \"${cid}\".`,\n );\n }\n\n const observeContract = deepCopyBundle(contract);\n observeContract.id = observeId;\n observeContract.mode = \"observe\";\n observeContract._observe = true;\n\n mc.push(observeContract);\n observes.push({\n contractId: cid,\n enforcedSource: contractSources.get(cid) ?? \"\",\n observedSource: label,\n });\n }\n merged.contracts = mc;\n\n if (\"tools\" in layer) {\n const mt = (merged.tools ?? {}) as Record<string, unknown>;\n for (const [name, cfg] of Object.entries(layer.tools as Record<string, unknown>)) {\n mt[name] = { ...(cfg as Record<string, unknown>) };\n }\n merged.tools = mt;\n }\n\n if (\"metadata\" in layer) {\n const mm = (merged.metadata ?? {}) as Record<string, unknown>;\n for (const [k, v] of Object.entries(layer.metadata as Record<string, unknown>)) mm[k] = v;\n merged.metadata = mm;\n }\n}\n","/** Built-in operators for YAML condition evaluation. */\n\n/** Cap regex input to prevent catastrophic backtracking DoS. */\nexport const MAX_REGEX_INPUT = 10_000;\n\n// ---------------------------------------------------------------------------\n// Operator implementations\n// ---------------------------------------------------------------------------\n\nfunction opEquals(fieldValue: unknown, opValue: unknown): boolean {\n return fieldValue === opValue;\n}\n\nfunction opNotEquals(fieldValue: unknown, opValue: unknown): boolean {\n return fieldValue !== opValue;\n}\n\nfunction opIn(fieldValue: unknown, opValue: unknown[]): boolean {\n return opValue.includes(fieldValue);\n}\n\nfunction opNotIn(fieldValue: unknown, opValue: unknown[]): boolean {\n return !opValue.includes(fieldValue);\n}\n\nfunction opContains(fieldValue: unknown, opValue: string): boolean {\n if (typeof fieldValue !== \"string\") throw new TypeError();\n return fieldValue.includes(opValue);\n}\n\nfunction opContainsAny(fieldValue: unknown, opValue: string[]): boolean {\n if (typeof fieldValue !== \"string\") throw new TypeError();\n return opValue.some((v) => fieldValue.includes(v));\n}\n\nfunction opStartsWith(fieldValue: unknown, opValue: string): boolean {\n if (typeof fieldValue !== \"string\") throw new TypeError();\n return fieldValue.startsWith(opValue);\n}\n\nfunction opEndsWith(fieldValue: unknown, opValue: string): boolean {\n if (typeof fieldValue !== \"string\") throw new TypeError();\n return fieldValue.endsWith(opValue);\n}\n\nfunction opMatches(fieldValue: unknown, opValue: string | RegExp): boolean {\n if (typeof fieldValue !== \"string\") throw new TypeError();\n const truncated = fieldValue.slice(0, MAX_REGEX_INPUT);\n if (opValue instanceof RegExp) {\n return opValue.test(truncated);\n }\n return new RegExp(opValue).test(truncated);\n}\n\nfunction opMatchesAny(\n fieldValue: unknown,\n opValue: Array<string | RegExp>,\n): boolean {\n if (typeof fieldValue !== \"string\") throw new TypeError();\n const truncated = fieldValue.slice(0, MAX_REGEX_INPUT);\n return opValue.some((p) =>\n p instanceof RegExp ? p.test(truncated) : new RegExp(p).test(truncated),\n );\n}\n\nfunction opGt(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== \"number\") throw new TypeError();\n return fieldValue > opValue;\n}\n\nfunction opGte(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== \"number\") throw new TypeError();\n return fieldValue >= opValue;\n}\n\nfunction opLt(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== \"number\") throw new TypeError();\n return fieldValue < opValue;\n}\n\nfunction opLte(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== \"number\") throw new TypeError();\n return fieldValue <= opValue;\n}\n\n// ---------------------------------------------------------------------------\n// Operator dispatch table\n// ---------------------------------------------------------------------------\n\nexport type OperatorFn = (fieldValue: unknown, opValue: unknown) => boolean;\n\nexport const OPERATORS: Readonly<Record<string, OperatorFn>> = {\n equals: opEquals,\n not_equals: opNotEquals,\n in: opIn as OperatorFn,\n not_in: opNotIn as OperatorFn,\n contains: opContains as OperatorFn,\n contains_any: opContainsAny as OperatorFn,\n starts_with: opStartsWith as OperatorFn,\n ends_with: opEndsWith as OperatorFn,\n matches: opMatches as OperatorFn,\n matches_any: opMatchesAny as OperatorFn,\n gt: opGt as OperatorFn,\n gte: opGte as OperatorFn,\n lt: opLt as OperatorFn,\n lte: opLte as OperatorFn,\n};\n\n/** All built-in operator names (including \"exists\" which is special-cased). */\nexport const BUILTIN_OPERATOR_NAMES: ReadonlySet<string> = new Set([\n ...Object.keys(OPERATORS),\n \"exists\",\n]);\n","/** Selector resolution — map YAML selector paths to ToolEnvelope values. */\n\nimport type { ToolEnvelope } from \"../envelope.js\";\nimport type { CustomSelector } from \"./evaluator.js\";\n\n// ---------------------------------------------------------------------------\n// Sentinel for \"field not found\"\n// ---------------------------------------------------------------------------\n\nconst _MISSING: unique symbol = Symbol(\"MISSING\");\nexport type Missing = typeof _MISSING;\nexport { _MISSING };\n\n// ---------------------------------------------------------------------------\n// Built-in selector prefixes — custom selectors must not use these\n// ---------------------------------------------------------------------------\n\nexport const BUILTIN_SELECTOR_PREFIXES: ReadonlySet<string> = new Set([\n \"environment\",\n \"tool\",\n \"args\",\n \"principal\",\n \"output\",\n \"env\",\n \"metadata\",\n]);\n\n// ---------------------------------------------------------------------------\n// Selector resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a dotted selector path to a value from the envelope.\n * Returns `_MISSING` if the field is not found at any level.\n *\n * NOTE: ToolEnvelope uses camelCase (toolName, userId, serviceId, orgId,\n * ticketRef) but YAML selectors use snake_case (tool.name, principal.user_id).\n * This function maps between the two.\n */\nexport function resolveSelector(\n selector: string,\n envelope: ToolEnvelope,\n outputText?: string | null,\n customSelectors?: Readonly<Record<string, CustomSelector>> | null,\n): unknown {\n if (selector === \"environment\") return envelope.environment;\n if (selector === \"tool.name\") return envelope.toolName;\n\n if (selector.startsWith(\"args.\")) {\n return resolveNested(selector.slice(5), envelope.args as Record<string, unknown>);\n }\n\n if (selector.startsWith(\"principal.\")) {\n if (envelope.principal == null) return _MISSING;\n const rest = selector.slice(10);\n // Map YAML snake_case selectors to TS camelCase properties\n if (rest === \"user_id\") return envelope.principal.userId;\n if (rest === \"service_id\") return envelope.principal.serviceId;\n if (rest === \"org_id\") return envelope.principal.orgId;\n if (rest === \"role\") return envelope.principal.role;\n if (rest === \"ticket_ref\") return envelope.principal.ticketRef;\n if (rest.startsWith(\"claims.\")) {\n return resolveNested(\n rest.slice(7),\n envelope.principal.claims as Record<string, unknown>,\n );\n }\n return _MISSING;\n }\n\n if (selector === \"output.text\") {\n return outputText == null ? _MISSING : outputText;\n }\n\n // SECURITY NOTE (Python parity): env.* selector intentionally reads from\n // process.env, matching Python's os.environ.get(). This is by design — YAML\n // contracts use env.* to gate behavior on environment variables (e.g.,\n // env.EDICTUM_MODE). The message template expansion layer handles secret\n // redaction. Bundle authors control which env vars are referenced; untrusted\n // YAML bundles should not be loaded without review.\n if (selector.startsWith(\"env.\")) {\n const varName = selector.slice(4);\n const raw = process.env[varName];\n if (raw == null) return _MISSING;\n return coerceEnvValue(raw);\n }\n\n if (selector.startsWith(\"metadata.\")) {\n return resolveNested(\n selector.slice(9),\n envelope.metadata as Record<string, unknown>,\n );\n }\n\n // Custom selectors: match prefix before first dot\n if (customSelectors) {\n const dotPos = selector.indexOf(\".\");\n if (dotPos > 0) {\n const prefix = selector.slice(0, dotPos);\n if (Object.hasOwn(customSelectors, prefix)) {\n const resolver = customSelectors[prefix] as CustomSelector;\n const data = resolver(envelope);\n const rest = selector.slice(dotPos + 1);\n return resolveNested(rest, data);\n }\n }\n }\n\n return _MISSING;\n}\n\n// ---------------------------------------------------------------------------\n// Nested path resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a dotted path through nested dicts.\n * Returns `_MISSING` if any intermediate key is absent or not a dict.\n */\nexport function resolveNested(path: string, data: unknown): unknown {\n const parts = path.split(\".\");\n let current = data;\n for (const part of parts) {\n if (current == null || typeof current !== \"object\") return _MISSING;\n const obj = current as Record<string, unknown>;\n if (!Object.hasOwn(obj, part)) return _MISSING;\n current = obj[part];\n }\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// Env value coercion\n// ---------------------------------------------------------------------------\n\n/** Coerce an env var string to a typed value for operator comparison. */\nexport function coerceEnvValue(raw: string): string | boolean | number {\n const low = raw.toLowerCase();\n if (low === \"true\") return true;\n if (low === \"false\") return false;\n const asInt = parseInt(raw, 10);\n if (!isNaN(asInt) && String(asInt) === raw) return asInt;\n const asFloat = parseFloat(raw);\n if (!isNaN(asFloat) && String(asFloat) === raw) return asFloat;\n return raw;\n}\n","/** Condition Evaluator — resolve selectors and apply operators against ToolEnvelope. */\n\nimport type { ToolEnvelope } from \"../envelope.js\";\nimport { OPERATORS, BUILTIN_OPERATOR_NAMES } from \"./operators.js\";\nimport { _MISSING, resolveSelector } from \"./selectors.js\";\n\n// Re-export for external consumers\nexport { BUILTIN_OPERATOR_NAMES };\nexport { MAX_REGEX_INPUT } from \"./operators.js\";\nexport { _MISSING, BUILTIN_SELECTOR_PREFIXES, resolveSelector } from \"./selectors.js\";\nexport type { Missing } from \"./selectors.js\";\n// Aliased re-exports for backward-compatible names\nexport { resolveNested as _resolveNested, coerceEnvValue as _coerceEnvValue } from \"./selectors.js\";\n\n// ---------------------------------------------------------------------------\n// PolicyError — sentinel for type mismatches (fail-closed)\n// ---------------------------------------------------------------------------\n\n/**\n * Sentinel indicating a type mismatch or evaluation error.\n *\n * Converts to `true` conceptually — errors trigger the contract (fail-closed).\n * Callers should treat PolicyError as \"condition matched\" and apply\n * deny/warn + policyError flag.\n */\nexport class PolicyError {\n readonly message: string;\n constructor(message: string) {\n this.message = message;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Custom extension types\n// ---------------------------------------------------------------------------\n\nexport type CustomOperator = (fieldValue: unknown, opValue: unknown) => boolean;\nexport type CustomSelector = (envelope: ToolEnvelope) => Record<string, unknown>;\n\nexport interface EvaluateOptions {\n readonly customOperators?: Readonly<Record<string, CustomOperator>> | null;\n readonly customSelectors?: Readonly<Record<string, CustomSelector>> | null;\n}\n\n// ---------------------------------------------------------------------------\n// Main entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate a boolean expression tree against an envelope.\n *\n * Returns `true` if the expression matches, `false` if not.\n * Returns a `PolicyError` if a type mismatch or evaluation error occurs\n * (caller should treat as deny/warn + policyError).\n *\n * Missing fields always evaluate to `false` (contract doesn't fire).\n */\nexport function evaluateExpression(\n expr: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText?: string | null,\n options?: EvaluateOptions,\n): boolean | PolicyError {\n const customOps = options?.customOperators ?? null;\n const customSels = options?.customSelectors ?? null;\n\n if (\"all\" in expr) {\n return _evalAll(expr.all as Record<string, unknown>[], envelope, outputText, customOps, customSels);\n }\n if (\"any\" in expr) {\n return _evalAny(expr.any as Record<string, unknown>[], envelope, outputText, customOps, customSels);\n }\n if (\"not\" in expr) {\n return _evalNot(expr.not as Record<string, unknown>, envelope, outputText, customOps, customSels);\n }\n\n // Leaf node: exactly one selector key (schema enforces single-key leaves).\n // Guard: if a malformed leaf has multiple keys, fail-closed with PolicyError\n // rather than silently dropping extra keys. Python takes next(iter(leaf))\n // which also ignores extras — this is a strictness improvement.\n const leafKeys = Object.keys(expr);\n if (leafKeys.length !== 1) {\n return new PolicyError(\n `Leaf expression must have exactly one selector key, got ${leafKeys.length}: [${leafKeys.join(\", \")}]`,\n );\n }\n return _evalLeaf(expr, envelope, outputText, customOps, customSels);\n}\n\n// ---------------------------------------------------------------------------\n// Boolean AST nodes\n// ---------------------------------------------------------------------------\n\nfunction _evalAll(\n exprs: Record<string, unknown>[],\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n for (const expr of exprs) {\n const result = evaluateExpression(expr, envelope, outputText, {\n customOperators: customOps, customSelectors: customSels,\n });\n if (result instanceof PolicyError) return result;\n if (!result) return false;\n }\n return true;\n}\n\nfunction _evalAny(\n exprs: Record<string, unknown>[],\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n for (const expr of exprs) {\n const result = evaluateExpression(expr, envelope, outputText, {\n customOperators: customOps, customSelectors: customSels,\n });\n if (result instanceof PolicyError) return result;\n if (result) return true;\n }\n return false;\n}\n\nfunction _evalNot(\n expr: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n const result = evaluateExpression(expr, envelope, outputText, {\n customOperators: customOps, customSelectors: customSels,\n });\n if (result instanceof PolicyError) return result;\n return !result;\n}\n\nfunction _evalLeaf(\n leaf: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n const selector = Object.keys(leaf)[0] as string;\n const operatorBlock = leaf[selector] as Record<string, unknown>;\n const value = resolveSelector(selector, envelope, outputText, customSels);\n const opName = Object.keys(operatorBlock)[0] as string;\n const opValue = operatorBlock[opName];\n return _applyOperator(opName, value, opValue, selector, customOps);\n}\n\n// ---------------------------------------------------------------------------\n// Operator application\n// ---------------------------------------------------------------------------\n\n/** Apply a single operator to a resolved field value. */\nfunction _applyOperator(\n op: string,\n fieldValue: unknown,\n opValue: unknown,\n selector: string,\n customOperators: Readonly<Record<string, CustomOperator>> | null,\n): boolean | PolicyError {\n // exists is special — works on _MISSING\n if (op === \"exists\") {\n const isPresent = fieldValue !== _MISSING && fieldValue != null;\n return isPresent === opValue;\n }\n\n // All other operators: missing field -> false\n if (fieldValue === _MISSING || fieldValue == null) return false;\n\n try {\n if (Object.hasOwn(OPERATORS, op)) return (OPERATORS[op] as (fv: unknown, ov: unknown) => boolean)(fieldValue, opValue);\n if (customOperators && Object.hasOwn(customOperators, op)) {\n return Boolean((customOperators[op] as CustomOperator)(fieldValue, opValue));\n }\n return new PolicyError(`Unknown operator: '${op}'`);\n } catch {\n return new PolicyError(\n `Type mismatch: operator '${op}' cannot be applied to ` +\n `selector '${selector}' value ${typeof fieldValue}`,\n );\n }\n}\n","/** Compiler utilities — validation, regex precompilation, message expansion. */\n\nimport { EdictumConfigError } from \"../errors.js\";\nimport { RedactionPolicy } from \"../redaction.js\";\nimport type { ToolEnvelope } from \"../envelope.js\";\nimport {\n BUILTIN_OPERATOR_NAMES,\n _MISSING,\n resolveSelector,\n type CustomSelector,\n} from \"./evaluator.js\";\n\n// ---------------------------------------------------------------------------\n// Placeholder expansion\n// ---------------------------------------------------------------------------\n\nconst _PLACEHOLDER_RE = /\\{([^}]+)\\}/g;\nconst _PLACEHOLDER_CAP = 200;\n\n/**\n * Expand {placeholder} tokens in a message template.\n *\n * Missing placeholders are kept as-is. Each expansion is capped at 200 chars.\n * Values that look like secrets are redacted.\n */\nexport function expandMessage(\n template: string,\n envelope: ToolEnvelope,\n outputText?: string | null,\n customSelectors?: Readonly<Record<string, CustomSelector>> | null,\n): string {\n const redaction = new RedactionPolicy();\n\n return template.replace(_PLACEHOLDER_RE, (match, selectorRaw: string) => {\n const value = resolveSelector(selectorRaw, envelope, outputText, customSelectors);\n if (value === _MISSING || value == null) return match;\n let text = String(value);\n if (redaction._looksLikeSecret(text)) text = \"[REDACTED]\";\n if (text.length > _PLACEHOLDER_CAP) text = text.slice(0, _PLACEHOLDER_CAP - 3) + \"...\";\n return text;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Operator validation\n// ---------------------------------------------------------------------------\n\n/** Validate that all operators used in the bundle are known (built-in or custom). */\nexport function validateOperators(\n bundle: Record<string, unknown>,\n customOperators: Readonly<Record<string, unknown>> | null,\n): void {\n const known = new Set([\n ...BUILTIN_OPERATOR_NAMES,\n ...Object.keys(customOperators ?? {}),\n ]);\n const contracts = (bundle.contracts ?? []) as Record<string, unknown>[];\n for (const contract of contracts) {\n const when = contract.when as Record<string, unknown> | undefined;\n if (when) {\n _validateExpressionOperators(when, known, contract.id as string);\n }\n }\n}\n\nfunction _validateExpressionOperators(\n expr: unknown,\n known: ReadonlySet<string>,\n contractId: string,\n): void {\n if (expr == null || typeof expr !== \"object\") return;\n const e = expr as Record<string, unknown>;\n\n if (\"all\" in e) {\n for (const sub of e.all as Record<string, unknown>[]) {\n _validateExpressionOperators(sub, known, contractId);\n }\n return;\n }\n if (\"any\" in e) {\n for (const sub of e.any as Record<string, unknown>[]) {\n _validateExpressionOperators(sub, known, contractId);\n }\n return;\n }\n if (\"not\" in e) {\n _validateExpressionOperators(e.not, known, contractId);\n return;\n }\n\n // Leaf node: selector -> operator\n for (const [, operator] of Object.entries(e)) {\n if (operator != null && typeof operator === \"object\") {\n for (const opName of Object.keys(operator as Record<string, unknown>)) {\n if (!known.has(opName)) {\n throw new EdictumConfigError(\n `Contract '${contractId}': unknown operator '${opName}'`,\n );\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Regex precompilation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively walk an expression tree and compile regex patterns.\n *\n * Replaces string values under `matches` and `matches_any` with\n * pre-compiled RegExp objects so the evaluator never recompiles on every call.\n */\nexport function precompileRegexes(expr: unknown): unknown {\n if (expr == null || typeof expr !== \"object\") return expr;\n const e = expr as Record<string, unknown>;\n\n if (\"all\" in e) {\n return { all: (e.all as unknown[]).map(precompileRegexes) };\n }\n if (\"any\" in e) {\n return { any: (e.any as unknown[]).map(precompileRegexes) };\n }\n if (\"not\" in e) {\n return { not: precompileRegexes(e.not) };\n }\n\n // Leaf node: selector -> operator\n const compiled: Record<string, unknown> = {};\n for (const [selector, operator] of Object.entries(e)) {\n if (operator == null || typeof operator !== \"object\") {\n compiled[selector] = operator;\n continue;\n }\n const newOp = { ...(operator as Record<string, unknown>) };\n if (\"matches\" in newOp && typeof newOp.matches === \"string\") {\n newOp.matches = new RegExp(newOp.matches);\n }\n if (\"matches_any\" in newOp && Array.isArray(newOp.matches_any)) {\n newOp.matches_any = (newOp.matches_any as string[]).map(\n (p) => (typeof p === \"string\" ? new RegExp(p) : p),\n );\n }\n compiled[selector] = newOp;\n }\n return compiled;\n}\n\n// ---------------------------------------------------------------------------\n// Output pattern extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Walk an expression tree and collect regex patterns from output.text leaves.\n *\n * Returns a flat list of compiled RegExp objects found under `matches` or\n * `matches_any` operators where the selector is `output.text`.\n * By the time this runs, `precompileRegexes` has already converted strings.\n */\nexport function extractOutputPatterns(expr: unknown): RegExp[] {\n if (expr == null || typeof expr !== \"object\") return [];\n const e = expr as Record<string, unknown>;\n\n if (\"all\" in e) {\n const patterns: RegExp[] = [];\n for (const sub of e.all as unknown[]) {\n patterns.push(...extractOutputPatterns(sub));\n }\n return patterns;\n }\n if (\"any\" in e) {\n const patterns: RegExp[] = [];\n for (const sub of e.any as unknown[]) {\n patterns.push(...extractOutputPatterns(sub));\n }\n return patterns;\n }\n if (\"not\" in e) {\n return extractOutputPatterns(e.not);\n }\n\n // Leaf node\n const collected: RegExp[] = [];\n for (const [selector, operator] of Object.entries(e)) {\n if (selector !== \"output.text\" || operator == null || typeof operator !== \"object\") continue;\n const op = operator as Record<string, unknown>;\n if (\"matches\" in op && op.matches instanceof RegExp) {\n collected.push(op.matches);\n }\n if (\"matches_any\" in op && Array.isArray(op.matches_any)) {\n for (const p of op.matches_any) {\n if (p instanceof RegExp) collected.push(p);\n }\n }\n }\n return collected;\n}\n","/** Contract compilation — compile individual YAML contracts into callable objects. */\n\nimport { Verdict } from \"../contracts.js\";\nimport type { ToolEnvelope } from \"../envelope.js\";\nimport { EdictumConfigError } from \"../errors.js\";\nimport type { OperationLimits } from \"../limits.js\";\nimport type { Session } from \"../session.js\";\nimport { evaluateExpression, PolicyError, type CustomOperator, type CustomSelector } from \"./evaluator.js\";\nimport { expandMessage, extractOutputPatterns, precompileRegexes } from \"./compiler-utils.js\";\n\n/** Shared evaluation logic for pre/post check functions. */\nfunction _evalAndVerdict(\n whenExpr: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n messageTemplate: string,\n tags: string[],\n thenMetadata: Record<string, unknown>,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): Verdict {\n try {\n const result = evaluateExpression(whenExpr, envelope, outputText, {\n customOperators: customOps, customSelectors: customSels,\n });\n if (result instanceof PolicyError) {\n const msg = expandMessage(messageTemplate, envelope, outputText, customSels);\n return Verdict.fail(msg, { tags, policyError: true, ...thenMetadata });\n }\n if (result) {\n const msg = expandMessage(messageTemplate, envelope, outputText, customSels);\n return Verdict.fail(msg, { tags, ...thenMetadata });\n }\n return Verdict.pass_();\n } catch (exc) {\n const msg = expandMessage(messageTemplate, envelope, outputText, customSels);\n return Verdict.fail(msg, { tags, policyError: true, errorDetail: String(exc), ...thenMetadata });\n }\n}\n\n/** Stamp _edictum_observe on the result if the contract is in observe mode. */\nfunction _maybeObserve(result: Record<string, unknown>, contract: Record<string, unknown>): void {\n if (contract._observe === true || contract._shadow === true) result._edictum_observe = true;\n}\n\n// ---------------------------------------------------------------------------\n// Pre-contract compilation\n// ---------------------------------------------------------------------------\n\nexport function compilePre(\n contract: Record<string, unknown>, mode: string,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): Record<string, unknown> {\n const contractId = contract.id as string;\n const tool = contract.tool as string;\n const whenExpr = precompileRegexes(contract.when) as Record<string, unknown>;\n const then = contract.then as Record<string, unknown>;\n const msgTpl = then.message as string;\n const tags = (then.tags ?? []) as string[];\n const meta = (then.metadata ?? {}) as Record<string, unknown>;\n\n const check = (envelope: ToolEnvelope): Verdict =>\n _evalAndVerdict(whenExpr, envelope, undefined, msgTpl, tags, meta, customOps, customSels);\n\n const result: Record<string, unknown> = {\n check, name: contractId, tool, type: \"precondition\",\n mode: mode as \"enforce\" | \"observe\",\n _edictum_type: \"precondition\", _edictum_tool: tool, _edictum_when: null,\n _edictum_mode: mode, _edictum_id: contractId, _edictum_source: \"yaml_precondition\",\n _edictum_effect: (then.effect as string) ?? \"deny\",\n _edictum_timeout: (then.timeout as number) ?? 300,\n _edictum_timeout_effect: (then.timeout_effect as string) ?? \"deny\",\n };\n _maybeObserve(result, contract);\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Post-contract compilation\n// ---------------------------------------------------------------------------\n\nexport function compilePost(\n contract: Record<string, unknown>, mode: string,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): Record<string, unknown> {\n const contractId = contract.id as string;\n const tool = contract.tool as string;\n const whenExpr = precompileRegexes(contract.when) as Record<string, unknown>;\n const then = contract.then as Record<string, unknown>;\n const msgTpl = then.message as string;\n const tags = (then.tags ?? []) as string[];\n const meta = (then.metadata ?? {}) as Record<string, unknown>;\n\n const check = (envelope: ToolEnvelope, response: unknown): Verdict => {\n const outputText = response != null ? String(response) : undefined;\n return _evalAndVerdict(whenExpr, envelope, outputText, msgTpl, tags, meta, customOps, customSels);\n };\n\n const effectValue = (then.effect as string) ?? \"warn\";\n const result: Record<string, unknown> = {\n check, name: contractId, tool, type: \"postcondition\",\n mode: mode as \"enforce\" | \"observe\",\n effect: effectValue,\n _edictum_type: \"postcondition\", _edictum_tool: tool, _edictum_when: null,\n _edictum_mode: mode, _edictum_id: contractId, _edictum_source: \"yaml_postcondition\",\n _edictum_effect: effectValue,\n _edictum_redact_patterns: extractOutputPatterns(whenExpr),\n };\n _maybeObserve(result, contract);\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Session contract compilation\n// ---------------------------------------------------------------------------\n\nexport function compileSession(\n contract: Record<string, unknown>,\n mode: string,\n limits: OperationLimits,\n): Record<string, unknown> {\n const contractId = contract.id as string;\n const then = contract.then as Record<string, unknown>;\n const messageTemplate = then.message as string;\n const tags = (then.tags ?? []) as string[];\n const thenMetadata = (then.metadata ?? {}) as Record<string, unknown>;\n const capturedLimits = { ...limits };\n\n const check = async (session: Session): Promise<Verdict> => {\n const execCount = await session.executionCount();\n if (execCount >= capturedLimits.maxToolCalls) {\n return Verdict.fail(messageTemplate, { tags, ...thenMetadata });\n }\n const attemptCount = await session.attemptCount();\n if (attemptCount >= capturedLimits.maxAttempts) {\n return Verdict.fail(messageTemplate, { tags, ...thenMetadata });\n }\n return Verdict.pass_();\n };\n\n const result: Record<string, unknown> = {\n check, name: contractId, type: \"session_contract\",\n _edictum_type: \"session_contract\",\n _edictum_mode: mode,\n _edictum_id: contractId,\n _edictum_message: messageTemplate,\n _edictum_tags: tags,\n _edictum_then_metadata: thenMetadata,\n _edictum_source: \"yaml_session\",\n };\n if (contract._observe === true || contract._shadow === true) {\n result._edictum_observe = true;\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Session limits merging\n// ---------------------------------------------------------------------------\n\n/**\n * Merge session contract limits into existing OperationLimits.\n * Picks the more restrictive value (lower) for each limit.\n */\nexport function mergeSessionLimits(\n contract: Record<string, unknown>,\n existing: OperationLimits,\n): OperationLimits {\n const sessionLimits = contract.limits as Record<string, unknown>;\n let maxToolCalls = existing.maxToolCalls;\n let maxAttempts = existing.maxAttempts;\n const maxCallsPerTool: Record<string, number> = { ...existing.maxCallsPerTool };\n\n if (\"max_tool_calls\" in sessionLimits) {\n const raw = sessionLimits.max_tool_calls;\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n throw new EdictumConfigError(`Session limit max_tool_calls must be a finite number, got: ${String(raw)}`);\n }\n maxToolCalls = Math.min(maxToolCalls, raw);\n }\n if (\"max_attempts\" in sessionLimits) {\n const raw = sessionLimits.max_attempts;\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n throw new EdictumConfigError(`Session limit max_attempts must be a finite number, got: ${String(raw)}`);\n }\n maxAttempts = Math.min(maxAttempts, raw);\n }\n if (\"max_calls_per_tool\" in sessionLimits) {\n const perTool = sessionLimits.max_calls_per_tool as Record<string, unknown>;\n for (const [tool, limit] of Object.entries(perTool)) {\n if (typeof limit !== \"number\" || !Number.isFinite(limit)) {\n throw new EdictumConfigError(\n `Session limit max_calls_per_tool['${tool}'] must be a finite number, got: ${String(limit)}`,\n );\n }\n if (Object.hasOwn(maxCallsPerTool, tool)) {\n maxCallsPerTool[tool] = Math.min(maxCallsPerTool[tool] as number, limit);\n } else {\n maxCallsPerTool[tool] = limit;\n }\n }\n }\n return { maxAttempts, maxToolCalls, maxCallsPerTool };\n}\n","/** Sandbox contract compiler — extract/classify tool call resources and compile sandbox contracts. */\n\nimport { realpathSync } from \"node:fs\";\nimport { resolve as pathResolve } from \"node:path\";\n\nimport type { ToolEnvelope } from \"../envelope.js\";\nimport { fnmatch } from \"../fnmatch.js\";\n\n// ---------------------------------------------------------------------------\n// Shell tokenization\n// ---------------------------------------------------------------------------\n\n/** Pattern for shell redirection operators at token start. */\nconst _REDIRECT_PREFIX_RE = /^(?:\\d*>>|>>|\\d*>|>|<<|<)/;\n\n/**\n * Shell command separators and metacharacters that allow chaining\n * multiple commands. If any of these appear in a raw command string,\n * the command is unsafe — the shell would execute multiple commands.\n *\n * Covers: ; | && || \\n \\r $() backtick ${} <()\n */\nconst _SHELL_SEPARATOR_RE = /[;|&\\n\\r`]|\\$\\(|\\$\\{|<\\(/;\n\n/**\n * Shell-aware tokenization of a command string.\n *\n * Handles single/double quotes. Strips shell redirection operators from\n * token prefixes so paths after redirects (e.g. >/etc/passwd) are exposed.\n * Falls back to basic split with quote stripping on parse error.\n */\nexport function tokenizeCommand(cmd: string): string[] {\n const rawTokens = _shlexSplit(cmd);\n\n const tokens: string[] = [];\n for (const t of rawTokens) {\n const stripped = t.replace(_REDIRECT_PREFIX_RE, \"\");\n if (stripped) tokens.push(stripped);\n }\n return tokens;\n}\n\n/** Minimal shlex.split() port — handle single/double quotes. */\nfunction _shlexSplit(s: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let inSingle = false;\n let inDouble = false;\n let i = 0;\n\n try {\n while (i < s.length) {\n const ch = s.charAt(i);\n if (inSingle) {\n if (ch === \"'\") { inSingle = false; } else { current += ch; }\n } else if (inDouble) {\n if (ch === '\\\\' && i + 1 < s.length) {\n // Backslash escaping inside double quotes: \\\", \\\\, \\$, \\`, \\newline\n const next = s.charAt(i + 1);\n if (next === '\"' || next === '\\\\' || next === '$' || next === '`' || next === '\\n') {\n current += next;\n i++;\n } else {\n // Literal backslash for other characters (POSIX behavior)\n current += ch;\n }\n } else if (ch === '\"') { inDouble = false; } else { current += ch; }\n } else if (ch === \"'\") {\n inSingle = true;\n } else if (ch === '\"') {\n inDouble = true;\n } else if (ch === \" \" || ch === \"\\t\") {\n if (current) { tokens.push(current); current = \"\"; }\n } else {\n current += ch;\n }\n i++;\n }\n // Unclosed quotes — fall back\n if (inSingle || inDouble) {\n return s.split(/\\s+/).filter(Boolean).map((t) => t.replace(/^['\"]|['\"]$/g, \"\"));\n }\n if (current) tokens.push(current);\n return tokens;\n } catch {\n return s.split(/\\s+/).filter(Boolean).map((t) => t.replace(/^['\"]|['\"]$/g, \"\"));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Path-like argument keys\n// ---------------------------------------------------------------------------\n\nconst _PATH_ARG_KEYS = new Set([\n \"path\", \"file_path\", \"filePath\", \"directory\", \"dir\",\n \"folder\", \"target\", \"destination\", \"source\", \"src\", \"dst\",\n]);\n\n/** Resolve a path via realpathSync, falling back to path.resolve for non-existent paths. */\nfunction _realpath(p: string): string {\n try {\n return realpathSync(p);\n } catch {\n return pathResolve(p);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Resource extraction\n// ---------------------------------------------------------------------------\n\n/** Extract file paths from an envelope for sandbox evaluation. */\nexport function extractPaths(envelope: ToolEnvelope): string[] {\n const paths: string[] = [];\n const seen = new Set<string>();\n\n function add(p: string): void {\n if (!p) return;\n const resolved = _realpath(p);\n if (!seen.has(resolved)) { seen.add(resolved); paths.push(resolved); }\n }\n\n if (envelope.filePath) add(envelope.filePath);\n\n const args = envelope.args as Record<string, unknown>;\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === \"string\" && _PATH_ARG_KEYS.has(key)) add(value);\n }\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === \"string\" && value.startsWith(\"/\") && !_PATH_ARG_KEYS.has(key)) add(value);\n }\n\n const cmd = envelope.bashCommand ?? (args.command as string | undefined) ?? \"\";\n if (cmd) {\n for (const token of tokenizeCommand(cmd)) {\n if (token.startsWith(\"/\")) add(token);\n }\n }\n return paths;\n}\n\n/** Extract the first command token from an envelope (shell-aware). */\nexport function extractCommand(envelope: ToolEnvelope): string | null {\n const cmd = envelope.bashCommand ?? (envelope.args as Record<string, unknown>).command;\n if (!cmd || typeof cmd !== \"string\") return null;\n const stripped = cmd.trim();\n if (!stripped) return null;\n\n // Check for shell command separators/metacharacters BEFORE extracting.\n // If any are present, the shell would execute multiple commands — return\n // sentinel value that never matches any allowlist.\n if (_SHELL_SEPARATOR_RE.test(stripped)) return \"\\x00\";\n\n const rawFirst = stripped.split(/\\s/)[0] ?? \"\";\n if (_REDIRECT_PREFIX_RE.test(rawFirst)) return \"\\x00\";\n\n const tokens = tokenizeCommand(stripped);\n return tokens.length > 0 ? (tokens[0] ?? null) : null;\n}\n\n/** Extract URL strings from envelope args (shell-aware). */\nexport function extractUrls(envelope: ToolEnvelope): string[] {\n const urls: string[] = [];\n const seen = new Set<string>();\n\n function addUrl(u: string): void {\n if (!seen.has(u)) { seen.add(u); urls.push(u); }\n }\n\n for (const value of Object.values(envelope.args)) {\n if (typeof value !== \"string\" || !value.includes(\"://\")) continue;\n if (extractHostname(value) !== null) {\n addUrl(value);\n } else {\n for (const token of tokenizeCommand(value)) {\n if (token.includes(\"://\") && extractHostname(token) !== null) addUrl(token);\n }\n }\n }\n return urls;\n}\n\n/** Extract hostname from a URL string. */\nexport function extractHostname(url: string): string | null {\n try {\n return new URL(url).hostname || null;\n } catch {\n return null;\n }\n}\n\n/** Check if hostname matches any domain pattern (supports wildcards). */\nexport function domainMatches(hostname: string, patterns: string[]): boolean {\n return patterns.some((p) => fnmatch(hostname, p));\n}\n","/**\n * Minimal Python fnmatch.fnmatch() port for glob pattern matching.\n *\n * Used by Edictum for contract tool filtering and hook registration.\n */\n\n/**\n * Match a name against a glob pattern (fnmatch-style).\n *\n * Supports: `*` (any sequence), `?` (any single char), literal match.\n * Does NOT support `[...]` character classes (not used by edictum contracts).\n *\n * Input capped at 10,000 characters to prevent regex DoS.\n */\nexport function fnmatch(name: string, pattern: string): boolean {\n if (pattern === \"*\") return true;\n if (!pattern.includes(\"*\") && !pattern.includes(\"?\")) {\n return name === pattern;\n }\n\n // Cap input length for regex DoS prevention\n const safeName = name.length > 10_000 ? name.slice(0, 10_000) : name;\n const safePattern =\n pattern.length > 10_000 ? pattern.slice(0, 10_000) : pattern;\n\n // Convert glob to regex: escape regex chars, then replace glob wildcards\n let regex = \"\";\n for (let i = 0; i < safePattern.length; i++) {\n const ch = safePattern[i] ?? \"\";\n if (ch === \"*\") {\n regex += \".*\";\n } else if (ch === \"?\") {\n regex += \".\";\n } else if (\".+^${}()|[]\\\\\".includes(ch)) {\n regex += \"\\\\\" + ch;\n } else {\n regex += ch;\n }\n }\n\n return new RegExp(\"^\" + regex + \"$\").test(safeName);\n}\n","/** compileSandbox — compile a sandbox contract YAML dict into a callable with metadata. */\n\nimport { Verdict } from \"../contracts.js\";\nimport type { ToolEnvelope } from \"../envelope.js\";\nimport { expandMessage } from \"./compiler-utils.js\";\nimport {\n extractPaths,\n extractCommand,\n extractUrls,\n extractHostname,\n domainMatches,\n} from \"./sandbox-compiler.js\";\n\nimport { realpathSync } from \"node:fs\";\nimport { resolve as pathResolve } from \"node:path\";\n\n/** Resolve a path via realpathSync, falling back to path.resolve. */\nfunction _realpath(p: string): string {\n try {\n return realpathSync(p);\n } catch {\n return pathResolve(p);\n }\n}\n\n/** Check if a path is within an allowed prefix. */\nfunction _pathWithin(filePath: string, prefix: string): boolean {\n return filePath === prefix || filePath.startsWith(prefix.replace(/\\/+$/, \"\") + \"/\");\n}\n\n/**\n * Compile a sandbox contract into a callable with _edictum_* metadata.\n *\n * The returned object has a `check` function and stamped metadata properties\n * for pipeline routing.\n */\nexport function compileSandbox(\n contract: Record<string, unknown>,\n mode: string,\n): Record<string, unknown> {\n const contractId = contract.id as string;\n\n // Normalize tool/tools to a list\n const toolPatterns: string[] = \"tools\" in contract\n ? (contract.tools as string[])\n : [contract.tool as string];\n\n const within = ((contract.within ?? []) as string[]).map(_realpath);\n const notWithin = ((contract.not_within ?? []) as string[]).map(_realpath);\n const allows = (contract.allows ?? {}) as Record<string, unknown>;\n const notAllows = (contract.not_allows ?? {}) as Record<string, unknown>;\n const allowedCommands = (allows.commands ?? []) as string[];\n const allowedDomains = (allows.domains ?? []) as string[];\n const blockedDomains = (notAllows.domains ?? []) as string[];\n const outside = (contract.outside as string) ?? \"deny\";\n const messageTemplate = (contract.message as string) ?? \"Tool call outside sandbox boundary.\";\n const timeout = (contract.timeout as number) ?? 300;\n const timeoutEffect = (contract.timeout_effect as string) ?? \"deny\";\n\n const check = (envelope: ToolEnvelope): Verdict => {\n // Path checks\n // SECURITY LIMITATION (Python parity — intentional fail-open on empty paths):\n // If extractPaths() returns empty (e.g., relative paths, ~, $HOME, or args\n // that don't match known path keys), within/not_within enforcement is silently\n // skipped. This matches Python's behavior — sandbox only checks paths it can\n // extract. A tool call with unrecognized path arguments will pass through\n // unchecked. This is a known gap: an attacker who crafts args that bypass\n // extractPaths() can evade sandbox path restrictions.\n // Mitigations: (1) use command allowlists as a complementary control,\n // (2) restrict tool access at the adapter level, (3) validate tool args\n // via precondition contracts that match the specific arg patterns.\n if (within.length > 0 || notWithin.length > 0) {\n const paths = extractPaths(envelope);\n if (paths.length > 0) {\n for (const p of paths) {\n for (const excluded of notWithin) {\n if (_pathWithin(p, excluded)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope));\n }\n }\n }\n if (within.length > 0) {\n for (const p of paths) {\n if (!within.some((allowed) => _pathWithin(p, allowed))) {\n return Verdict.fail(expandMessage(messageTemplate, envelope));\n }\n }\n }\n }\n }\n\n // Command checks\n if (allowedCommands.length > 0) {\n const firstToken = extractCommand(envelope);\n if (firstToken !== null && !allowedCommands.includes(firstToken)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope));\n }\n }\n\n // Domain checks\n const urls = extractUrls(envelope);\n if (urls.length > 0) {\n for (const url of urls) {\n const hostname = extractHostname(url);\n if (hostname) {\n if (blockedDomains.length > 0 && domainMatches(hostname, blockedDomains)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope));\n }\n if (allowedDomains.length > 0 && !domainMatches(hostname, allowedDomains)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope));\n }\n } else if (allowedDomains.length > 0) {\n // Fail-closed: URLs without extractable hostname (file://, data:, etc.)\n // cannot be verified against domain allowlist → deny\n return Verdict.fail(expandMessage(messageTemplate, envelope));\n }\n }\n }\n\n return Verdict.pass_();\n };\n\n const result: Record<string, unknown> = {\n check,\n name: contractId,\n tool: toolPatterns.length === 1 ? toolPatterns[0] : undefined,\n _edictum_type: \"sandbox\",\n _edictum_tools: toolPatterns,\n _edictum_mode: mode,\n _edictum_id: contractId,\n _edictum_source: \"yaml_sandbox\",\n _edictum_effect: outside,\n _edictum_timeout: timeout,\n _edictum_timeout_effect: timeoutEffect,\n };\n\n // Use _observe (TS) not _shadow (Python). Strict === true to prevent\n // truthy coercion of non-boolean values (e.g., strings, numbers).\n if (contract._observe === true || contract._shadow === true) {\n result._edictum_observe = true;\n }\n\n return result;\n}\n","/** Compiler — convert parsed YAML contracts into contract objects and OperationLimits. */\n\nimport type { OperationLimits } from \"../limits.js\";\nimport { DEFAULT_LIMITS } from \"../limits.js\";\nimport type { CustomOperator, CustomSelector } from \"./evaluator.js\";\nimport { EdictumConfigError } from \"../errors.js\";\nimport { validateOperators } from \"./compiler-utils.js\";\nimport { compilePre, compilePost, compileSession, mergeSessionLimits } from \"./compile-contracts.js\";\nimport { compileSandbox } from \"./sandbox-compile-fn.js\";\n\n// ---------------------------------------------------------------------------\n// CompiledBundle\n// ---------------------------------------------------------------------------\n\n/** Result of compiling a YAML contract bundle. */\nexport interface CompiledBundle {\n readonly preconditions: readonly unknown[];\n readonly postconditions: readonly unknown[];\n readonly sessionContracts: readonly unknown[];\n readonly sandboxContracts: readonly unknown[];\n readonly limits: OperationLimits;\n readonly defaultMode: string;\n readonly tools: Readonly<Record<string, Record<string, unknown>>>;\n}\n\n// ---------------------------------------------------------------------------\n// Compile options\n// ---------------------------------------------------------------------------\n\nexport interface CompileOptions {\n readonly customOperators?: Readonly<Record<string, CustomOperator>> | null;\n readonly customSelectors?: Readonly<Record<string, CustomSelector>> | null;\n}\n\n// ---------------------------------------------------------------------------\n// Main entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a validated YAML bundle into contract objects.\n *\n * @param bundle - A validated bundle dict (output of loadBundle).\n * @param options - Optional custom operators and selectors.\n * @returns CompiledBundle with preconditions, postconditions, sessionContracts,\n * and merged OperationLimits.\n */\nexport function compileContracts(\n bundle: Record<string, unknown>,\n options: CompileOptions = {},\n): CompiledBundle {\n const customOps = options?.customOperators ?? null;\n const customSels = options?.customSelectors ?? null;\n\n validateOperators(bundle, customOps);\n\n if (bundle.defaults == null || typeof bundle.defaults !== \"object\") {\n throw new EdictumConfigError(\n \"Bundle missing required 'defaults' section with 'mode' field\",\n );\n }\n const defaults = bundle.defaults as Record<string, unknown>;\n const defaultMode = defaults.mode as string;\n const preconditions: unknown[] = [];\n const postconditions: unknown[] = [];\n const sessionContracts: unknown[] = [];\n const sandboxContracts: unknown[] = [];\n let limits: OperationLimits = { ...DEFAULT_LIMITS };\n\n const contracts = (bundle.contracts ?? []) as Record<string, unknown>[];\n for (const contract of contracts) {\n // Skip disabled contracts\n if (contract.enabled === false) continue;\n\n const contractType = contract.type as string;\n const contractMode = (contract.mode as string) ?? defaultMode;\n\n if (contractType === \"pre\") {\n preconditions.push(compilePre(contract, contractMode, customOps, customSels));\n } else if (contractType === \"post\") {\n postconditions.push(compilePost(contract, contractMode, customOps, customSels));\n } else if (contractType === \"session\") {\n // Use _observe (TS) not _shadow (Python)\n const isObserve =\n (contract._observe as boolean) ?? (contract._shadow as boolean) ?? false;\n if (!isObserve) {\n limits = mergeSessionLimits(contract, limits);\n }\n sessionContracts.push(compileSession(contract, contractMode, limits));\n } else if (contractType === \"sandbox\") {\n sandboxContracts.push(compileSandbox(contract, contractMode));\n } else {\n throw new EdictumConfigError(\n `Unknown contract type \"${contractType}\" in contract \"${contract.id ?? \"unknown\"}\". ` +\n `Expected \"pre\", \"post\", \"session\", or \"sandbox\".`,\n );\n }\n }\n\n const tools = (bundle.tools ?? {}) as Record<string, Record<string, unknown>>;\n\n return {\n preconditions,\n postconditions,\n sessionContracts,\n sandboxContracts,\n limits,\n defaultMode,\n tools,\n };\n}\n","/** YAML Bundle Loader — parse, validate, compute bundle hash. */\n\nimport { createHash } from \"node:crypto\";\nimport { readFileSync, realpathSync, statSync } from \"node:fs\";\n\nimport { EdictumConfigError } from \"../errors.js\";\nimport {\n validateSchema,\n validateUniqueIds,\n validateRegexes,\n validatePreSelectors,\n validateSandboxContracts,\n} from \"./loader-validators.js\";\n\n// Re-export validators for direct access\nexport {\n validateSchema,\n validateUniqueIds,\n validateRegexes,\n validatePreSelectors,\n validateSandboxContracts,\n} from \"./loader-validators.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum bundle file size in bytes (1 MB). */\nexport const MAX_BUNDLE_SIZE = 1_048_576;\n\n// ---------------------------------------------------------------------------\n// BundleHash\n// ---------------------------------------------------------------------------\n\n/** SHA256 hash of raw YAML bytes, used as policy_version. */\nexport interface BundleHash {\n readonly hex: string;\n}\n\n/** Compute SHA256 hash of raw YAML bytes. */\nexport function computeHash(rawBytes: Uint8Array): BundleHash {\n return { hex: createHash(\"sha256\").update(rawBytes).digest(\"hex\") };\n}\n\n// ---------------------------------------------------------------------------\n// YAML parsing helper\n// ---------------------------------------------------------------------------\n\n/** Load js-yaml or throw a helpful error. */\nfunction requireYaml(): { load(input: string): unknown } {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const yaml = require(\"js-yaml\") as { load(input: string): unknown };\n return yaml;\n } catch {\n throw new EdictumConfigError(\n \"The YAML engine requires js-yaml. Install it with: npm install js-yaml\",\n );\n }\n}\n\n/** Parse YAML content string, returning the parsed object. */\nfunction parseYaml(content: string): Record<string, unknown> {\n const yaml = requireYaml();\n let data: unknown;\n try {\n data = yaml.load(content);\n } catch (e) {\n throw new EdictumConfigError(`YAML parse error: ${String(e)}`);\n }\n if (data == null || typeof data !== \"object\" || Array.isArray(data)) {\n throw new EdictumConfigError(\"YAML document must be a mapping\");\n }\n return data as Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Validation pipeline\n// ---------------------------------------------------------------------------\n\n/** Run all bundle validations in sequence. */\nfunction validateBundle(data: Record<string, unknown>): void {\n validateSchema(data);\n validateUniqueIds(data);\n validateRegexes(data);\n validatePreSelectors(data);\n validateSandboxContracts(data);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Load and validate a YAML contract bundle from a file path.\n *\n * @returns Tuple of [parsed bundle dict, bundle hash].\n * @throws EdictumConfigError on validation failure.\n * @throws Error if the file does not exist.\n */\nexport function loadBundle(source: string): [Record<string, unknown>, BundleHash] {\n // Resolve symlinks before reading to prevent path traversal attacks.\n const resolved = realpathSync(source);\n const fileSize = statSync(resolved).size;\n if (fileSize > MAX_BUNDLE_SIZE) {\n throw new EdictumConfigError(\n `Bundle file too large (${fileSize} bytes, max ${MAX_BUNDLE_SIZE})`,\n );\n }\n\n const rawBytes = readFileSync(resolved);\n const bundleHash = computeHash(rawBytes);\n const data = parseYaml(rawBytes.toString(\"utf-8\"));\n\n validateBundle(data);\n return [data, bundleHash];\n}\n\n/**\n * Load and validate a YAML contract bundle from a string or bytes.\n *\n * Like {@link loadBundle} but accepts YAML content directly instead of\n * a file path. Useful when YAML is generated programmatically or fetched\n * from an API.\n *\n * @returns Tuple of [parsed bundle dict, bundle hash].\n * @throws EdictumConfigError on validation failure.\n */\nexport function loadBundleString(\n content: string | Uint8Array,\n): [Record<string, unknown>, BundleHash] {\n const rawBytes =\n typeof content === \"string\" ? new TextEncoder().encode(content) : content;\n\n if (rawBytes.length > MAX_BUNDLE_SIZE) {\n throw new EdictumConfigError(\n `Bundle content too large (${rawBytes.length} bytes, max ${MAX_BUNDLE_SIZE})`,\n );\n }\n\n const bundleHash = computeHash(rawBytes);\n const text =\n typeof content === \"string\" ? content : new TextDecoder().decode(rawBytes);\n const data = parseYaml(text);\n\n validateBundle(data);\n return [data, bundleHash];\n}\n","/** Loader validation helpers — schema, uniqueness, regex, selector, and sandbox checks. */\n\nimport { EdictumConfigError } from \"../errors.js\";\n\n// ---------------------------------------------------------------------------\n// Schema validation (structural — no JSON Schema dependency)\n// ---------------------------------------------------------------------------\n\n/**\n * Basic structural validation of a parsed YAML bundle.\n *\n * Checks apiVersion, kind, metadata, and contracts array.\n * Full JSON Schema validation requires the edictum-schemas package (future).\n */\nexport function validateSchema(data: Record<string, unknown>): void {\n if (data.apiVersion !== \"edictum/v1\") {\n throw new EdictumConfigError(\n `Schema validation failed: apiVersion must be 'edictum/v1', got '${String(data.apiVersion)}'`,\n );\n }\n if (data.kind !== \"ContractBundle\") {\n throw new EdictumConfigError(\n `Schema validation failed: kind must be 'ContractBundle', got '${String(data.kind)}'`,\n );\n }\n if (data.metadata != null && typeof data.metadata !== \"object\") {\n throw new EdictumConfigError(\"Schema validation failed: metadata must be an object\");\n }\n if (!Array.isArray(data.contracts)) {\n throw new EdictumConfigError(\"Schema validation failed: contracts must be an array\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Unique IDs\n// ---------------------------------------------------------------------------\n\n// Reject control characters in contract IDs — null bytes, newlines, carriage\n// returns, and other C0/C1 control chars could corrupt storage keys or logs.\nconst CONTROL_CHAR_RE = /[\\x00-\\x1f\\x7f-\\x9f]/;\n\n/** Validate a single contract ID for dangerous characters. */\nfunction validateContractId(contractId: string): void {\n if (CONTROL_CHAR_RE.test(contractId)) {\n throw new EdictumConfigError(\n `Contract id contains control characters: '${contractId.replace(CONTROL_CHAR_RE, \"\\\\x??\")}'`,\n );\n }\n}\n\n/** Ensure all contract IDs are unique within the bundle and free of control characters. */\nexport function validateUniqueIds(data: Record<string, unknown>): void {\n const ids = new Set<string>();\n const contracts = (data.contracts ?? []) as Record<string, unknown>[];\n for (const contract of contracts) {\n const contractId = contract.id as string | undefined;\n if (contractId != null) {\n validateContractId(contractId);\n if (ids.has(contractId)) {\n throw new EdictumConfigError(`Duplicate contract id: '${contractId}'`);\n }\n ids.add(contractId);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Regex validation\n// ---------------------------------------------------------------------------\n\n/** Compile all regex patterns at load time to catch invalid patterns early. */\nexport function validateRegexes(data: Record<string, unknown>): void {\n const contracts = (data.contracts ?? []) as Record<string, unknown>[];\n for (const contract of contracts) {\n const when = contract.when;\n if (when != null) {\n validateExpressionRegexes(when as Record<string, unknown>);\n }\n }\n}\n\n/** Recursively validate regex patterns in expressions. */\nfunction validateExpressionRegexes(expr: unknown): void {\n if (expr == null || typeof expr !== \"object\") return;\n const e = expr as Record<string, unknown>;\n\n if (\"all\" in e) {\n for (const sub of e.all as unknown[]) validateExpressionRegexes(sub);\n return;\n }\n if (\"any\" in e) {\n for (const sub of e.any as unknown[]) validateExpressionRegexes(sub);\n return;\n }\n if (\"not\" in e) {\n validateExpressionRegexes(e.not);\n return;\n }\n\n // Leaf node: selector -> operator\n for (const operator of Object.values(e)) {\n if (operator == null || typeof operator !== \"object\") continue;\n const op = operator as Record<string, unknown>;\n if (\"matches\" in op) tryCompileRegex(op.matches as string);\n if (\"matches_any\" in op) {\n for (const pattern of op.matches_any as string[]) tryCompileRegex(pattern);\n }\n }\n}\n\n/** Attempt to compile a regex, raising EdictumConfigError on failure. */\nfunction tryCompileRegex(pattern: string): void {\n try {\n new RegExp(pattern);\n } catch (e) {\n throw new EdictumConfigError(`Invalid regex pattern '${pattern}': ${String(e)}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pre-selector validation\n// ---------------------------------------------------------------------------\n\n/** Reject output.text selectors in type: pre contracts (spec violation). */\nexport function validatePreSelectors(data: Record<string, unknown>): void {\n const contracts = (data.contracts ?? []) as Record<string, unknown>[];\n for (const contract of contracts) {\n if (contract.type !== \"pre\") continue;\n const when = contract.when;\n if (when != null && expressionHasSelector(when as Record<string, unknown>, \"output.text\")) {\n throw new EdictumConfigError(\n `Contract '${(contract.id as string) ?? \"?\"}': output.text selector is not available in type: pre contracts`,\n );\n }\n }\n}\n\n/** Check if an expression tree contains a specific selector. */\nfunction expressionHasSelector(expr: unknown, target: string): boolean {\n if (expr == null || typeof expr !== \"object\") return false;\n const e = expr as Record<string, unknown>;\n if (\"all\" in e) return (e.all as unknown[]).some((sub) => expressionHasSelector(sub, target));\n if (\"any\" in e) return (e.any as unknown[]).some((sub) => expressionHasSelector(sub, target));\n if (\"not\" in e) return expressionHasSelector(e.not, target);\n return target in e;\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox contract validation\n// ---------------------------------------------------------------------------\n\n/** Validate sandbox contract field dependencies. */\nexport function validateSandboxContracts(data: Record<string, unknown>): void {\n const contracts = (data.contracts ?? []) as Record<string, unknown>[];\n for (const contract of contracts) {\n if (contract.type !== \"sandbox\") continue;\n const cid = (contract.id as string) ?? \"?\";\n\n if (\"not_within\" in contract && !(\"within\" in contract)) {\n throw new EdictumConfigError(`Contract '${cid}': not_within requires within to also be set`);\n }\n if (\"not_allows\" in contract && !(\"allows\" in contract)) {\n throw new EdictumConfigError(`Contract '${cid}': not_allows requires allows to also be set`);\n }\n if (\"not_allows\" in contract) {\n const notAllows = (contract.not_allows ?? {}) as Record<string, unknown>;\n if (\"domains\" in notAllows) {\n const allows = (contract.allows ?? {}) as Record<string, unknown>;\n if (!(\"domains\" in allows)) {\n throw new EdictumConfigError(\n `Contract '${cid}': not_allows.domains requires allows.domains to also be set`,\n );\n }\n }\n }\n }\n}\n","/** Edictum — Runtime contract enforcement for AI agent tool calls. */\n\nexport const VERSION = \"0.1.0\";\n\n// Errors\nexport { EdictumConfigError, EdictumDenied, EdictumToolError } from \"./errors.js\";\n\n// Envelope & Classification\nexport {\n BashClassifier,\n createEnvelope,\n createPrincipal,\n deepFreeze,\n SideEffect,\n ToolRegistry,\n _validateToolName,\n} from \"./envelope.js\";\nexport type { CreateEnvelopeOptions, Principal, ToolEnvelope } from \"./envelope.js\";\n\n// Contracts\nexport { Verdict } from \"./contracts.js\";\nexport type { Precondition, Postcondition, SessionContract } from \"./contracts.js\";\n\n// Hooks\nexport { HookDecision, HookResult } from \"./hooks.js\";\n\n// Limits\nexport { DEFAULT_LIMITS } from \"./limits.js\";\nexport type { OperationLimits } from \"./limits.js\";\n\n// Types (internal, but exported for adapter authors)\nexport type { HookRegistration, ToolConfig } from \"./types.js\";\n\n// Storage\nexport { MemoryBackend } from \"./storage.js\";\nexport type { StorageBackend } from \"./storage.js\";\n\n// Session\nexport { Session } from \"./session.js\";\n\n// Approval\nexport {\n ApprovalStatus,\n LocalApprovalBackend,\n} from \"./approval.js\";\nexport type {\n ApprovalBackend,\n ApprovalDecision,\n ApprovalRequest,\n} from \"./approval.js\";\n\n// Audit\nexport {\n AuditAction,\n CollectingAuditSink,\n CompositeSink,\n createAuditEvent,\n FileAuditSink,\n MarkEvictedError,\n StdoutAuditSink,\n} from \"./audit.js\";\nexport type { AuditEvent, AuditSink } from \"./audit.js\";\n\n// Redaction\nexport { RedactionPolicy } from \"./redaction.js\";\n\n// Evaluation\nexport { createContractResult, createEvaluationResult } from \"./evaluation.js\";\nexport type { ContractResult, EvaluationResult } from \"./evaluation.js\";\n\n// Findings\nexport {\n buildFindings,\n classifyFinding,\n createFinding,\n createPostCallResult,\n} from \"./findings.js\";\nexport type { Finding, PostCallResult, PostDecisionLike } from \"./findings.js\";\n\n// Internal contract types (for adapter and YAML engine authors)\nexport type {\n GuardLike,\n InternalContract,\n InternalPrecondition,\n InternalPostcondition,\n InternalSessionContract,\n InternalSandboxContract,\n} from \"./internal-contracts.js\";\n\n// Compiled state\nexport { createCompiledState } from \"./compiled-state.js\";\nexport type { CompiledState } from \"./compiled-state.js\";\n\n// Pipeline\nexport { GovernancePipeline, createPreDecision, createPostDecision } from \"./pipeline.js\";\nexport type { PreDecision, PostDecision } from \"./pipeline.js\";\n\n// Guard\nexport { Edictum } from \"./guard.js\";\nexport type { EdictumOptions } from \"./guard.js\";\n\n// Runner (framework-agnostic tool execution)\nexport { defaultSuccessCheck, run } from \"./runner.js\";\nexport type { RunOptions } from \"./runner.js\";\n\n// Dry-run evaluation\nexport type { BatchCall, EvaluateOptions } from \"./dry-run.js\";\n\n// Fnmatch\nexport { fnmatch } from \"./fnmatch.js\";\n\n// YAML Factory\nexport { fromYaml, fromYamlString, reload } from \"./factory.js\";\nexport type { YamlFactoryOptions, FromYamlOptions, ReloadOptions } from \"./factory.js\";\n\n// YAML Engine (public API)\nexport {\n evaluateExpression,\n PolicyError,\n BUILTIN_OPERATOR_NAMES,\n BUILTIN_SELECTOR_PREFIXES,\n MAX_REGEX_INPUT,\n} from \"./yaml-engine/index.js\";\nexport type {\n CustomOperator,\n CustomSelector,\n} from \"./yaml-engine/index.js\";\nexport {\n compileContracts,\n loadBundle,\n loadBundleString,\n computeHash,\n MAX_BUNDLE_SIZE,\n composeBundles,\n expandMessage,\n validateOperators,\n} from \"./yaml-engine/index.js\";\nexport type {\n CompiledBundle,\n CompileOptions,\n BundleHash,\n ComposedBundle,\n CompositionReport,\n} from \"./yaml-engine/index.js\";\n"],"mappings":"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","names":["createHash","realpathSync","pathResolve","_realpath","realpathSync","realpathSync","createHash","run"]}
1
+ {"version":3,"sources":["../src/limits.ts","../src/storage.ts","../src/findings.ts","../src/compiled-state.ts","../src/guard.ts","../src/factory.ts","../src/yaml-engine/composer.ts","../src/yaml-engine/operators.ts","../src/yaml-engine/selectors.ts","../src/yaml-engine/evaluator.ts","../src/yaml-engine/compiler-utils.ts","../src/yaml-engine/compile-contracts.ts","../src/fnmatch.ts","../src/yaml-engine/resolve-path.ts","../src/yaml-engine/sandbox-compiler.ts","../src/yaml-engine/sandbox-compile-fn.ts","../src/yaml-engine/compiler.ts","../src/yaml-engine/loader.ts","../src/yaml-engine/loader-validators.ts","../src/yaml-engine/loader-field-validators.ts","../src/yaml-engine/loader-expression-validators.ts","../src/index.ts"],"sourcesContent":["/** Operation Limits — tool call and attempt caps. */\n\n/**\n * Operation limits for an agent session.\n *\n * Two counter types:\n * - maxAttempts: caps ALL PreToolUse events (including denied)\n * - maxToolCalls: caps EXECUTIONS only (PostToolUse)\n *\n * Both are checked. Whichever fires first wins.\n */\nexport interface OperationLimits {\n readonly maxAttempts: number\n readonly maxToolCalls: number\n readonly maxCallsPerTool: Readonly<Record<string, number>>\n}\n\nexport const DEFAULT_LIMITS: OperationLimits = Object.freeze({\n maxAttempts: 500,\n maxToolCalls: 200,\n maxCallsPerTool: Object.freeze({}),\n})\n","/** StorageBackend interface + MemoryBackend implementation. */\n\n// ---------------------------------------------------------------------------\n// StorageBackend — protocol for persistent state storage\n// ---------------------------------------------------------------------------\n\n/**\n * Protocol for persistent state storage.\n *\n * Requirements:\n * - increment() MUST be atomic\n * - get/set for simple key-value\n *\n * v0.1.0: No append() method (counters only, no list ops).\n */\nexport interface StorageBackend {\n get(key: string): Promise<string | null>\n set(key: string, value: string): Promise<void>\n delete(key: string): Promise<void>\n increment(key: string, amount?: number): Promise<number>\n}\n\n// ---------------------------------------------------------------------------\n// MemoryBackend — in-memory implementation for dev/testing\n// ---------------------------------------------------------------------------\n\n/**\n * In-memory storage for development and testing.\n *\n * WARNING: State lost on restart. Session contracts reset.\n * Suitable for: local dev, tests, single-process scripts.\n *\n * Node.js is single-threaded — Map operations are atomic.\n * No lock needed (unlike Python's asyncio.Lock).\n */\nexport class MemoryBackend implements StorageBackend {\n private readonly _data: Map<string, string> = new Map()\n private readonly _counters: Map<string, number> = new Map()\n\n async get(key: string): Promise<string | null> {\n const strVal = this._data.get(key)\n if (strVal !== undefined) {\n return strVal\n }\n const numVal = this._counters.get(key)\n if (numVal !== undefined) {\n return numVal === Math.trunc(numVal) ? String(Math.trunc(numVal)) : String(numVal)\n }\n return null\n }\n\n async set(key: string, value: string): Promise<void> {\n this._data.set(key, value)\n }\n\n async delete(key: string): Promise<void> {\n this._data.delete(key)\n this._counters.delete(key)\n }\n\n async increment(key: string, amount: number = 1): Promise<number> {\n const current = this._counters.get(key) ?? 0\n const next = current + amount\n this._counters.set(key, next)\n return next\n }\n\n /**\n * Retrieve multiple values in a single operation.\n *\n * In-memory implementation: multiple Map lookups, no network overhead.\n */\n async batchGet(keys: readonly string[]): Promise<Record<string, string | null>> {\n const result: Record<string, string | null> = {}\n for (const key of keys) {\n result[key] = await this.get(key)\n }\n return result\n }\n}\n","/** Structured postcondition findings. */\n\n// ---------------------------------------------------------------------------\n// Finding\n// ---------------------------------------------------------------------------\n\n/**\n * A structured finding from a postcondition evaluation.\n *\n * Produced when a postcondition warns or detects an issue.\n * Returned to the caller via PostCallResult so they can\n * decide how to remediate.\n */\nexport interface Finding {\n readonly type: string\n readonly contractId: string\n readonly field: string\n readonly message: string\n readonly metadata: Readonly<Record<string, unknown>>\n}\n\n/** Create a frozen Finding with defaults for metadata. */\nexport function createFinding(\n fields: Pick<Finding, 'type' | 'contractId' | 'field' | 'message'> &\n Partial<Pick<Finding, 'metadata'>>,\n): Finding {\n return Object.freeze({\n type: fields.type,\n contractId: fields.contractId,\n field: fields.field,\n message: fields.message,\n metadata: Object.freeze({ ...(fields.metadata ?? {}) }),\n })\n}\n\n// ---------------------------------------------------------------------------\n// PostCallResult\n// ---------------------------------------------------------------------------\n\n/**\n * Result from a governed tool call, including postcondition findings.\n *\n * Returned by adapter's postToolCall and available via asToolWrapper.\n *\n * When postconditionsPassed is false, the findings list contains\n * structured Finding objects describing what was detected. The caller\n * can then decide how to remediate (redact, replace, log, etc.).\n */\nexport interface PostCallResult {\n readonly result: unknown\n readonly postconditionsPassed: boolean\n readonly findings: readonly Finding[]\n readonly outputSuppressed: boolean\n}\n\n/** Create a PostCallResult with defaults. */\nexport function createPostCallResult(\n fields: Pick<PostCallResult, 'result'> & Partial<Omit<PostCallResult, 'result'>>,\n): PostCallResult {\n return Object.freeze({\n result: fields.result,\n postconditionsPassed: fields.postconditionsPassed ?? true,\n findings: Object.freeze([...(fields.findings ?? [])]),\n outputSuppressed: fields.outputSuppressed ?? false,\n })\n}\n\n// ---------------------------------------------------------------------------\n// classifyFinding\n// ---------------------------------------------------------------------------\n\n/**\n * Classify a postcondition finding type from contract ID and message.\n *\n * Returns a standard finding type string.\n */\nexport function classifyFinding(contractId: string, verdictMessage: string): string {\n const contractLower = contractId.toLowerCase()\n const messageLower = (verdictMessage || '').toLowerCase()\n\n const piiTerms = ['pii', 'ssn', 'patient', 'name', 'dob']\n if (piiTerms.some((term) => contractLower.includes(term) || messageLower.includes(term))) {\n return 'pii_detected'\n }\n\n const secretTerms = ['secret', 'token', 'key', 'credential', 'password']\n if (secretTerms.some((term) => contractLower.includes(term) || messageLower.includes(term))) {\n return 'secret_detected'\n }\n\n const limitTerms = ['session', 'limit', 'max_calls', 'budget']\n if (limitTerms.some((term) => contractLower.includes(term) || messageLower.includes(term))) {\n return 'limit_exceeded'\n }\n\n return 'policy_violation'\n}\n\n// ---------------------------------------------------------------------------\n// PostDecision — structural type (pipeline.ts doesn't exist yet)\n// ---------------------------------------------------------------------------\n\n/**\n * Structural type for the PostDecision fields consumed by buildFindings.\n *\n * The full PostDecision lives in pipeline.ts. This captures only the\n * subset needed here to avoid a circular import.\n */\nexport interface PostDecisionLike {\n readonly contractsEvaluated: ReadonlyArray<{\n readonly passed?: boolean\n readonly name: string\n readonly message?: string\n readonly metadata?: Record<string, unknown>\n }>\n}\n\n// ---------------------------------------------------------------------------\n// buildFindings\n// ---------------------------------------------------------------------------\n\n/**\n * Build Finding objects from a PostDecision's failed postconditions.\n *\n * The `field` value is extracted from `metadata.field` if the\n * contract provides it (e.g. `Verdict.fail(\"msg\", { field: \"output.text\" })`),\n * otherwise defaults to `\"output\"` for postconditions.\n */\nexport function buildFindings(postDecision: PostDecisionLike): Finding[] {\n const findings: Finding[] = []\n for (const cr of postDecision.contractsEvaluated) {\n if (!cr.passed) {\n const meta = cr.metadata ?? {}\n findings.push(\n createFinding({\n type: classifyFinding(cr.name, cr.message ?? ''),\n contractId: cr.name,\n field: (meta.field as string) ?? 'output',\n message: cr.message ?? '',\n metadata: meta,\n }),\n )\n }\n }\n return findings\n}\n","/**\n * _CompiledState -- frozen snapshot of compiled contracts.\n *\n * All contract lists are readonly arrays (frozen). The entire state is\n * replaced atomically via a single reference assignment in reload(),\n * ensuring concurrent evaluations never see a mix of old and new\n * contracts.\n */\n\nimport { deepFreeze } from './envelope.js'\nimport type {\n InternalPrecondition,\n InternalPostcondition,\n InternalSessionContract,\n InternalSandboxContract,\n} from './internal-contracts.js'\nimport { DEFAULT_LIMITS } from './limits.js'\nimport type { OperationLimits } from './limits.js'\n\nexport interface CompiledState {\n readonly preconditions: readonly InternalPrecondition[]\n readonly postconditions: readonly InternalPostcondition[]\n readonly sessionContracts: readonly InternalSessionContract[]\n readonly sandboxContracts: readonly InternalSandboxContract[]\n readonly observePreconditions: readonly InternalPrecondition[]\n readonly observePostconditions: readonly InternalPostcondition[]\n readonly observeSessionContracts: readonly InternalSessionContract[]\n readonly observeSandboxContracts: readonly InternalSandboxContract[]\n readonly limits: OperationLimits\n readonly policyVersion: string | null\n}\n\nexport function createCompiledState(partial: Partial<CompiledState> = {}): CompiledState {\n return deepFreeze({\n preconditions: partial.preconditions ?? [],\n postconditions: partial.postconditions ?? [],\n sessionContracts: partial.sessionContracts ?? [],\n sandboxContracts: partial.sandboxContracts ?? [],\n observePreconditions: partial.observePreconditions ?? [],\n observePostconditions: partial.observePostconditions ?? [],\n observeSessionContracts: partial.observeSessionContracts ?? [],\n observeSandboxContracts: partial.observeSandboxContracts ?? [],\n limits: partial.limits ?? DEFAULT_LIMITS,\n policyVersion: partial.policyVersion ?? null,\n })\n}\n","/**\n * Core Edictum class -- construction, contract registry, and accessor methods.\n *\n * SIZE APPROVAL: This file exceeds 200 lines. It mirrors Python's _guard.py\n * (314 LOC) which is already the decomposed version of the original god class.\n * The contract classification + accessor methods form a cohesive unit.\n *\n * Minimum viable guard: constructor + contract classification + accessors.\n * run(), from_yaml(), from_server() are delegated methods added later.\n */\n\nimport { randomUUID } from 'node:crypto'\n\nimport type { ApprovalBackend } from './approval.js'\nimport {\n fromYaml as _fromYaml,\n fromYamlString as _fromYamlString,\n reload as _reload,\n} from './factory.js'\nimport type { FromYamlOptions, ReloadOptions, YamlFactoryOptions } from './factory.js'\nimport type { CompositionReport } from './yaml-engine/composer.js'\nimport { CollectingAuditSink, CompositeSink } from './audit.js'\nimport type { AuditSink } from './audit.js'\nimport { createCompiledState } from './compiled-state.js'\nimport { EdictumConfigError } from './errors.js'\nimport type { CompiledState } from './compiled-state.js'\nimport type { Precondition, Postcondition, SessionContract } from './contracts.js'\nimport { SideEffect, ToolRegistry } from './envelope.js'\nimport type { Principal, ToolEnvelope } from './envelope.js'\nimport type { EvaluationResult } from './evaluation.js'\nimport { fnmatch } from './fnmatch.js'\nimport type {\n GuardLike,\n InternalPrecondition,\n InternalPostcondition,\n InternalSessionContract,\n InternalSandboxContract,\n} from './internal-contracts.js'\nimport { DEFAULT_LIMITS } from './limits.js'\nimport type { OperationLimits } from './limits.js'\nimport { RedactionPolicy } from './redaction.js'\nimport { MemoryBackend } from './storage.js'\nimport type { StorageBackend } from './storage.js'\nimport type { HookRegistration } from './types.js'\n\n// ---------------------------------------------------------------------------\n// User contract type discrimination\n// ---------------------------------------------------------------------------\n\n/** User-facing contract with optional name (not in interface, but allowed). */\ntype NamedContract = { readonly name?: string }\n\nfunction isSessionContract(\n c: Precondition | Postcondition | SessionContract,\n): c is SessionContract {\n return !('tool' in c)\n}\n\n// ---------------------------------------------------------------------------\n// EdictumOptions\n// ---------------------------------------------------------------------------\n\n/** Constructor options for the Edictum guard. */\nexport interface EdictumOptions {\n readonly environment?: string\n readonly mode?: 'enforce' | 'observe'\n readonly limits?: OperationLimits\n readonly tools?: Record<string, { side_effect?: string; idempotent?: boolean }>\n readonly contracts?: ReadonlyArray<Precondition | Postcondition | SessionContract>\n readonly hooks?: ReadonlyArray<HookRegistration>\n readonly auditSink?: AuditSink | AuditSink[]\n readonly redaction?: RedactionPolicy\n readonly backend?: StorageBackend\n readonly policyVersion?: string\n readonly onDeny?: (envelope: ToolEnvelope, reason: string, source: string | null) => void\n readonly onAllow?: (envelope: ToolEnvelope) => void\n readonly successCheck?: (toolName: string, result: unknown) => boolean\n readonly principal?: Principal\n readonly principalResolver?: (toolName: string, toolInput: Record<string, unknown>) => Principal\n readonly approvalBackend?: ApprovalBackend\n}\n\n// ---------------------------------------------------------------------------\n// Edictum class\n// ---------------------------------------------------------------------------\n\n/**\n * Main configuration and entrypoint.\n *\n * Two usage modes:\n * 1. With framework adapter: use the appropriate adapter\n * 2. Framework-agnostic: use guard.run() directly\n */\nexport class Edictum implements GuardLike {\n readonly environment: string\n readonly mode: 'enforce' | 'observe'\n readonly backend: StorageBackend\n readonly redaction: RedactionPolicy\n readonly toolRegistry: ToolRegistry\n readonly auditSink: AuditSink\n\n private readonly _localSink: CollectingAuditSink\n private _state: CompiledState\n private readonly _beforeHooks: HookRegistration[]\n private readonly _afterHooks: HookRegistration[]\n private readonly _sessionId: string\n\n // Callbacks and resolution — not private because _runner.ts needs access\n // (Python's _runner.py accesses self._on_deny etc. directly)\n /** @internal */ readonly _onDeny:\n | ((envelope: ToolEnvelope, reason: string, source: string | null) => void)\n | null\n /** @internal */ readonly _onAllow: ((envelope: ToolEnvelope) => void) | null\n /** @internal */ readonly _successCheck: ((toolName: string, result: unknown) => boolean) | null\n private _principal: Principal | null\n private readonly _principalResolver:\n | ((toolName: string, toolInput: Record<string, unknown>) => Principal)\n | null\n /** @internal */ readonly _approvalBackend: ApprovalBackend | null\n\n constructor(options: EdictumOptions = {}) {\n this.environment = options.environment ?? 'production'\n this.mode = options.mode ?? 'enforce'\n this.backend = options.backend ?? new MemoryBackend()\n this.redaction = options.redaction ?? new RedactionPolicy()\n this._onDeny = options.onDeny ?? null\n this._onAllow = options.onAllow ?? null\n this._successCheck = options.successCheck ?? null\n this._principal = options.principal ?? null\n this._principalResolver = options.principalResolver ?? null\n this._approvalBackend = options.approvalBackend ?? null\n\n // Audit sink: local sink always present\n this._localSink = new CollectingAuditSink()\n if (Array.isArray(options.auditSink)) {\n this.auditSink = new CompositeSink([this._localSink, ...options.auditSink])\n } else if (options.auditSink != null) {\n this.auditSink = new CompositeSink([this._localSink, options.auditSink])\n } else {\n this.auditSink = this._localSink\n }\n\n // Build tool registry\n this.toolRegistry = new ToolRegistry()\n if (options.tools) {\n for (const [name, config] of Object.entries(options.tools)) {\n this.toolRegistry.register(\n name,\n (config.side_effect as SideEffect | undefined) ?? SideEffect.IRREVERSIBLE,\n config.idempotent ?? false,\n )\n }\n }\n\n // Classify contracts and build compiled state\n this._state = Edictum._classifyContracts(\n options.contracts ?? [],\n options.limits ?? DEFAULT_LIMITS,\n options.policyVersion ?? null,\n )\n\n // Hooks are not reloaded -- mutable lists are fine\n this._beforeHooks = []\n this._afterHooks = []\n for (const item of options.hooks ?? []) {\n this._registerHook(item)\n }\n\n // Persistent session ID for accumulating limits across run() calls\n this._sessionId = randomUUID()\n }\n\n // -----------------------------------------------------------------------\n // Properties\n // -----------------------------------------------------------------------\n\n /** The local in-memory audit event collector. Always present. */\n get localSink(): CollectingAuditSink {\n return this._localSink\n }\n\n /** Operation limits for the current contract set. */\n get limits(): OperationLimits {\n return this._state.limits\n }\n\n /** Update operation limits (replaces compiled state atomically). */\n set limits(value: OperationLimits) {\n this._state = createCompiledState({ ...this._state, limits: value })\n }\n\n /** SHA256 hash identifying the active contract bundle. */\n get policyVersion(): string | null {\n return this._state.policyVersion\n }\n\n /**\n * Replace the compiled state atomically.\n *\n * @internal — used by factory.ts reload(). Not part of the public API.\n */\n _replaceState(newState: CompiledState): void {\n this._state = newState\n }\n\n /**\n * Read the current compiled state.\n *\n * @internal — used by factory.ts reload(). Not part of the public API.\n */\n _getState(): CompiledState {\n return this._state\n }\n\n /** Update policy version (replaces compiled state atomically). */\n set policyVersion(value: string | null) {\n this._state = createCompiledState({\n ...this._state,\n policyVersion: value,\n })\n }\n\n /** The persistent session ID for this guard instance. */\n get sessionId(): string {\n return this._sessionId\n }\n\n // -----------------------------------------------------------------------\n // Principal\n // -----------------------------------------------------------------------\n\n /** Update the principal used for subsequent tool calls. */\n setPrincipal(principal: Principal): void {\n this._principal = principal\n }\n\n /** Resolve the principal for a tool call. */\n _resolvePrincipal(toolName: string, toolInput: Record<string, unknown>): Principal | null {\n if (this._principalResolver != null) {\n return this._principalResolver(toolName, toolInput)\n }\n return this._principal\n }\n\n // -----------------------------------------------------------------------\n // Hooks\n // -----------------------------------------------------------------------\n\n private _registerHook(item: HookRegistration): void {\n if (item.phase === 'before') {\n this._beforeHooks.push(item)\n } else {\n this._afterHooks.push(item)\n }\n }\n\n getHooks(phase: 'before' | 'after', envelope: ToolEnvelope): HookRegistration[] {\n const hooks = phase === 'before' ? this._beforeHooks : this._afterHooks\n return hooks.filter((h) => h.tool === '*' || fnmatch(envelope.toolName, h.tool))\n }\n\n // -----------------------------------------------------------------------\n // Contract accessors -- enforce mode\n // -----------------------------------------------------------------------\n\n getPreconditions(envelope: ToolEnvelope): InternalPrecondition[] {\n return Edictum._filterByTool(this._state.preconditions as InternalPrecondition[], envelope)\n }\n\n getPostconditions(envelope: ToolEnvelope): InternalPostcondition[] {\n return Edictum._filterByTool(this._state.postconditions as InternalPostcondition[], envelope)\n }\n\n getSessionContracts(): InternalSessionContract[] {\n return [...this._state.sessionContracts]\n }\n\n getSandboxContracts(envelope: ToolEnvelope): InternalSandboxContract[] {\n return Edictum._filterSandbox(\n this._state.sandboxContracts as InternalSandboxContract[],\n envelope,\n )\n }\n\n // -----------------------------------------------------------------------\n // Contract accessors -- observe mode\n // -----------------------------------------------------------------------\n\n getObservePreconditions(envelope: ToolEnvelope): InternalPrecondition[] {\n return Edictum._filterByTool(\n this._state.observePreconditions as InternalPrecondition[],\n envelope,\n )\n }\n\n getObservePostconditions(envelope: ToolEnvelope): InternalPostcondition[] {\n return Edictum._filterByTool(\n this._state.observePostconditions as InternalPostcondition[],\n envelope,\n )\n }\n\n getObserveSessionContracts(): InternalSessionContract[] {\n return [...this._state.observeSessionContracts]\n }\n\n getObserveSandboxContracts(envelope: ToolEnvelope): InternalSandboxContract[] {\n return Edictum._filterSandbox(\n this._state.observeSandboxContracts as InternalSandboxContract[],\n envelope,\n )\n }\n\n // -----------------------------------------------------------------------\n // Private helpers\n // -----------------------------------------------------------------------\n\n /**\n * Classify user-facing and internal contracts into enforce/observe lists.\n *\n * User-facing contracts (Precondition, Postcondition, SessionContract)\n * are converted to internal representations. Internal contracts (from\n * YAML compiler) carry _edictum_* metadata and are classified by their\n * _edictum_observe flag (Python uses _edictum_shadow — wire-format parity).\n */\n private static _classifyContracts(\n contracts: ReadonlyArray<Precondition | Postcondition | SessionContract>,\n limits: OperationLimits,\n policyVersion: string | null,\n ): CompiledState {\n const pre: InternalPrecondition[] = []\n const post: InternalPostcondition[] = []\n const session: InternalSessionContract[] = []\n const sandbox: InternalSandboxContract[] = []\n const oPre: InternalPrecondition[] = []\n const oPost: InternalPostcondition[] = []\n const oSession: InternalSessionContract[] = []\n const oSandbox: InternalSandboxContract[] = []\n\n for (const item of contracts) {\n const raw = item as unknown as Record<string, unknown>\n const edictumType = raw._edictum_type as string | undefined\n // Python YAML compiler emits _edictum_shadow; we accept both for wire-format parity\n const isObserve =\n (raw._edictum_observe as boolean) ?? (raw._edictum_shadow as boolean) ?? false\n\n if (edictumType != null) {\n // Internal contract (from YAML compiler)\n Edictum._classifyInternal(raw, edictumType, isObserve, {\n pre,\n post,\n session,\n sandbox,\n oPre,\n oPost,\n oSession,\n oSandbox,\n })\n } else if (isSessionContract(item)) {\n const name = (raw as NamedContract).name ?? 'anonymous'\n session.push({\n type: 'session_contract',\n name,\n check: (item as SessionContract).check,\n })\n } else if ('tool' in item && (item as { contractType?: string }).contractType === 'post') {\n const postItem = item as Postcondition\n const name = (raw as NamedContract).name ?? 'anonymous'\n post.push({\n type: 'postcondition',\n name,\n tool: postItem.tool,\n check: postItem.check,\n when: postItem.when,\n })\n } else if ('tool' in item) {\n // Fail-closed: reject unknown contractType and detect missing \"post\"\n const ct = (raw as { contractType?: unknown }).contractType\n if (ct != null && ct !== 'pre') {\n throw new EdictumConfigError(\n `Contract with tool \"${(item as Precondition).tool}\" has unknown contractType ` +\n `\"${String(ct)}\". Expected \"pre\" or omitted for Precondition, \"post\" for Postcondition.`,\n )\n }\n // Best-effort heuristic for JS consumers who forget contractType: \"post\".\n // NOTE: Function.length is unreliable for rest parameters (...args) and\n // default-valued params — both give length 0. This catches the common\n // case (explicit (envelope, output)) but cannot guarantee detection.\n // Always set contractType: \"post\" explicitly.\n if (ct == null && item.check.length >= 2) {\n throw new EdictumConfigError(\n `Contract with tool \"${(item as Precondition).tool}\" has a check function with ` +\n `${item.check.length} parameters (looks like a Postcondition) but is missing ` +\n `contractType: \"post\". Add it to prevent misclassification.`,\n )\n }\n const preItem = item as Precondition\n const name = (raw as NamedContract).name ?? 'anonymous'\n pre.push({\n type: 'precondition',\n name,\n tool: preItem.tool,\n check: preItem.check,\n when: preItem.when,\n })\n }\n }\n\n return createCompiledState({\n preconditions: pre,\n postconditions: post,\n sessionContracts: session,\n sandboxContracts: sandbox,\n observePreconditions: oPre,\n observePostconditions: oPost,\n observeSessionContracts: oSession,\n observeSandboxContracts: oSandbox,\n limits,\n policyVersion,\n })\n }\n\n /** Route an internal contract to the appropriate enforce/observe list. */\n private static _classifyInternal(\n raw: Record<string, unknown>,\n edictumType: string,\n isObserve: boolean,\n lists: {\n pre: InternalPrecondition[]\n post: InternalPostcondition[]\n session: InternalSessionContract[]\n sandbox: InternalSandboxContract[]\n oPre: InternalPrecondition[]\n oPost: InternalPostcondition[]\n oSession: InternalSessionContract[]\n oSandbox: InternalSandboxContract[]\n },\n ): void {\n const target = isObserve\n ? { pre: lists.oPre, post: lists.oPost, session: lists.oSession, sandbox: lists.oSandbox }\n : { pre: lists.pre, post: lists.post, session: lists.session, sandbox: lists.sandbox }\n\n if (edictumType === 'precondition') target.pre.push(raw as unknown as InternalPrecondition)\n else if (edictumType === 'postcondition')\n target.post.push(raw as unknown as InternalPostcondition)\n else if (edictumType === 'session_contract')\n target.session.push(raw as unknown as InternalSessionContract)\n else if (edictumType === 'sandbox')\n target.sandbox.push(raw as unknown as InternalSandboxContract)\n else {\n throw new EdictumConfigError(\n `Unknown _edictum_type \"${edictumType}\". ` +\n `Expected \"precondition\", \"postcondition\", \"session_contract\", or \"sandbox\".`,\n )\n }\n }\n\n /** Filter contracts by tool pattern and optional `when` guard. */\n private static _filterByTool<\n T extends {\n readonly tool: string\n readonly when?: ((envelope: ToolEnvelope) => boolean) | null\n },\n >(contracts: T[], envelope: ToolEnvelope): T[] {\n const result: T[] = []\n for (const p of contracts) {\n const tool = p.tool ?? '*'\n const when = p.when ?? null\n if (tool !== '*' && !fnmatch(envelope.toolName, tool)) {\n continue\n }\n if (when != null) {\n try {\n if (!when(envelope)) continue\n } catch {\n // Fail-closed: throwing predicate includes the contract (not excludes)\n // so it gets evaluated and can deny — safer than silently skipping.\n }\n }\n result.push(p)\n }\n return result\n }\n\n /** Filter sandbox contracts by tool patterns array. */\n private static _filterSandbox(\n contracts: InternalSandboxContract[],\n envelope: ToolEnvelope,\n ): InternalSandboxContract[] {\n const result: InternalSandboxContract[] = []\n for (const s of contracts) {\n const tools = s.tools ?? ['*']\n if (tools.some((p) => fnmatch(envelope.toolName, p))) {\n result.push(s)\n }\n }\n return result\n }\n\n // -----------------------------------------------------------------------\n // Delegated methods — run, evaluate, evaluateBatch\n // -----------------------------------------------------------------------\n\n /** Execute a tool call with full governance pipeline. */\n async run(\n toolName: string,\n args: Record<string, unknown>,\n toolCallable: (args: Record<string, unknown>) => unknown | Promise<unknown>,\n options?: {\n sessionId?: string\n environment?: string\n principal?: Principal\n },\n ): Promise<unknown> {\n const { run } = await import('./runner.js')\n return run(this, toolName, args, toolCallable, options)\n }\n\n /**\n * Dry-run evaluation of a tool call against all matching contracts.\n *\n * Never executes the tool. Evaluates exhaustively (no short-circuit).\n * Session contracts are skipped.\n */\n evaluate(\n toolName: string,\n args: Record<string, unknown>,\n options?: {\n principal?: Principal\n output?: string\n environment?: string\n },\n ): Promise<EvaluationResult> {\n // Dynamic import avoids circular dependency\n return import('./dry-run.js').then(({ evaluate }) => evaluate(this, toolName, args, options))\n }\n\n /** Evaluate a batch of tool calls. Thin wrapper over evaluate(). */\n evaluateBatch(\n calls: Array<{\n tool: string\n args?: Record<string, unknown>\n principal?: Record<string, unknown>\n output?: string | Record<string, unknown>\n environment?: string\n }>,\n ): Promise<EvaluationResult[]> {\n return import('./dry-run.js').then(({ evaluateBatch }) => evaluateBatch(this, calls))\n }\n\n // -----------------------------------------------------------------------\n // YAML factory methods — delegate to factory.ts\n // Circular dependency (factory.ts imports guard.ts) is safe because\n // ESM resolves all bindings before user code calls these methods.\n // -----------------------------------------------------------------------\n\n /**\n * Create an Edictum instance from one or more YAML contract bundle paths.\n *\n * When multiple paths are given, bundles are composed left-to-right\n * (later layers override earlier ones).\n *\n * When the trailing options object has `returnReport: true`, returns\n * a tuple of [Edictum, CompositionReport].\n */\n static fromYaml(\n ...args: [...string[], FromYamlOptions & { returnReport: true }]\n ): [Edictum, CompositionReport]\n static fromYaml(...args: [...string[], FromYamlOptions] | string[]): Edictum\n static fromYaml(\n ...args: [...string[], FromYamlOptions] | string[]\n ): Edictum | [Edictum, CompositionReport] {\n return _fromYaml(...args)\n }\n\n /**\n * Create an Edictum instance from a YAML string or Uint8Array.\n */\n static fromYamlString(content: string | Uint8Array, options?: YamlFactoryOptions): Edictum {\n return _fromYamlString(content, options)\n }\n\n /**\n * Atomically replace this guard's contracts from a YAML string.\n *\n * Pass customOperators/customSelectors if the new YAML uses custom\n * operators or selectors that were passed to fromYaml/fromYamlString.\n */\n reload(yamlContent: string, options?: ReloadOptions): void {\n _reload(this, yamlContent, options)\n }\n}\n","/**\n * Factory functions for creating Edictum instances from YAML bundles.\n *\n * Ports Python's _factory.py: fromYaml, fromYamlString, reload.\n *\n * SIZE APPROVAL: This file exceeds 200 lines. It mirrors Python's _factory.py\n * (384 LOC). The three factory functions share option types and helper logic\n * that would create unnecessary coupling if split.\n *\n * Guard.ts delegates to these via dynamic import to avoid circular deps.\n */\n\nimport { createHash } from 'node:crypto'\n\nimport type { ApprovalBackend } from './approval.js'\nimport type { AuditSink } from './audit.js'\nimport { EdictumConfigError } from './errors.js'\nimport type { Principal, ToolEnvelope } from './envelope.js'\nimport { Edictum } from './guard.js'\nimport type { OperationLimits } from './limits.js'\nimport type { RedactionPolicy } from './redaction.js'\nimport type { StorageBackend } from './storage.js'\nimport { composeBundles } from './yaml-engine/composer.js'\nimport type { CompositionReport } from './yaml-engine/composer.js'\nimport { compileContracts } from './yaml-engine/compiler.js'\nimport type { CustomOperator, CustomSelector } from './yaml-engine/evaluator.js'\nimport { loadBundle, loadBundleString } from './yaml-engine/loader.js'\n\n// ---------------------------------------------------------------------------\n// Shared options type\n// ---------------------------------------------------------------------------\n\n/** Options shared by fromYaml and fromYamlString. */\nexport interface YamlFactoryOptions {\n readonly mode?: 'enforce' | 'observe'\n readonly tools?: Record<string, { side_effect?: string; idempotent?: boolean }>\n readonly auditSink?: AuditSink | AuditSink[]\n readonly redaction?: RedactionPolicy\n readonly backend?: StorageBackend\n readonly environment?: string\n readonly onDeny?: (envelope: ToolEnvelope, reason: string, source: string | null) => void\n readonly onAllow?: (envelope: ToolEnvelope) => void\n readonly customOperators?: Record<string, CustomOperator>\n readonly customSelectors?: Record<string, CustomSelector>\n readonly successCheck?: (toolName: string, result: unknown) => boolean\n readonly principal?: Principal\n readonly principalResolver?: (toolName: string, toolInput: Record<string, unknown>) => Principal\n readonly approvalBackend?: ApprovalBackend\n}\n\n/** Options for fromYaml, extending base with returnReport. */\nexport interface FromYamlOptions extends YamlFactoryOptions {\n readonly returnReport?: boolean\n}\n\n// ---------------------------------------------------------------------------\n// fromYaml\n// ---------------------------------------------------------------------------\n\n/**\n * Create an Edictum instance from one or more YAML contract bundle paths.\n *\n * When multiple paths are given, bundles are composed left-to-right\n * (later layers override earlier ones).\n *\n * EXCEPTION TO \"ALL ASYNC\" RULE: This factory is intentionally synchronous,\n * matching Python's from_yaml(). File I/O uses Node's readFileSync and YAML\n * parsing is CPU-bound — neither benefits from async. The returned Edictum\n * instance's run()/evaluate()/evaluateBatch() methods are fully async.\n * Making this async would force all callers to await at module init time\n * for no concurrency benefit.\n */\nexport function fromYaml(\n ...args: [...string[], FromYamlOptions] | string[]\n): Edictum | [Edictum, CompositionReport] {\n // Separate paths from trailing options object\n let paths: string[]\n let options: FromYamlOptions\n\n const last = args[args.length - 1]\n if (typeof last === 'object' && last !== null && !Array.isArray(last)) {\n paths = args.slice(0, -1) as string[]\n options = last as FromYamlOptions\n } else {\n paths = args as string[]\n options = {}\n }\n\n if (paths.length === 0) {\n throw new EdictumConfigError('fromYaml() requires at least one path')\n }\n\n // Load all bundles\n const loaded: [Record<string, unknown>, { hex: string }][] = []\n for (const p of paths) {\n loaded.push(loadBundle(p))\n }\n\n let bundleData: Record<string, unknown>\n let policyVersion: string\n let report: CompositionReport\n\n if (loaded.length === 1) {\n const entry = loaded[0] as [Record<string, unknown>, { hex: string }]\n bundleData = entry[0]\n policyVersion = entry[1].hex\n report = { overriddenContracts: [], observeContracts: [] }\n } else {\n const bundleTuples: [Record<string, unknown>, string][] = loaded.map(([data], i) => [\n data,\n paths[i] as string,\n ])\n const composed = composeBundles(...bundleTuples)\n bundleData = composed.bundle\n report = composed.report\n policyVersion = createHash('sha256')\n .update(loaded.map(([, h]) => h.hex).join(':'))\n .digest('hex')\n }\n\n const compiled = compileContracts(bundleData, {\n customOperators: options.customOperators ?? null,\n customSelectors: options.customSelectors ?? null,\n })\n\n const guard = _buildGuard(compiled, policyVersion, options)\n\n if (options.returnReport) {\n return [guard, report]\n }\n return guard\n}\n\n// ---------------------------------------------------------------------------\n// fromYamlString\n// ---------------------------------------------------------------------------\n\n/**\n * Create an Edictum instance from a YAML string or Uint8Array.\n *\n * Like fromYaml but accepts YAML content directly instead of a file path.\n *\n * EXCEPTION TO \"ALL ASYNC\" RULE: Synchronous by design — see fromYaml docs.\n */\nexport function fromYamlString(\n content: string | Uint8Array,\n options: YamlFactoryOptions = {},\n): Edictum {\n const [bundleData, bundleHash] = loadBundleString(content)\n const policyVersion = bundleHash.hex\n\n const compiled = compileContracts(bundleData, {\n customOperators: options.customOperators ?? null,\n customSelectors: options.customSelectors ?? null,\n })\n\n return _buildGuard(compiled, policyVersion, options)\n}\n\n// ---------------------------------------------------------------------------\n// reload\n// ---------------------------------------------------------------------------\n\n/** Options for reload(). */\nexport interface ReloadOptions {\n readonly customOperators?: Record<string, CustomOperator>\n readonly customSelectors?: Record<string, CustomSelector>\n}\n\n/**\n * Atomically replace a guard's contracts from a YAML string.\n *\n * Builds a new CompiledState from the YAML content and swaps the\n * guard's internal state reference. Concurrent evaluations that\n * started before reload() see the old state; evaluations after\n * see the new state.\n */\nexport function reload(guard: Edictum, yamlContent: string, options: ReloadOptions = {}): void {\n const [bundleData, bundleHash] = loadBundleString(yamlContent)\n const compiled = compileContracts(bundleData, {\n customOperators: options.customOperators ?? null,\n customSelectors: options.customSelectors ?? null,\n })\n\n const allContracts = [\n ...compiled.preconditions,\n ...compiled.postconditions,\n ...compiled.sessionContracts,\n ...compiled.sandboxContracts,\n ] as unknown[]\n\n // Classify into enforce/observe lists via the same logic the constructor uses.\n // We build a temporary Edictum to leverage _classifyContracts, then steal its state.\n const temp = new Edictum({\n contracts: allContracts as never[],\n limits: compiled.limits,\n policyVersion: bundleHash.hex,\n })\n\n // Atomic state swap via package-internal methods\n guard._replaceState(temp._getState())\n}\n\n// ---------------------------------------------------------------------------\n// Internal: build guard from compiled bundle\n// ---------------------------------------------------------------------------\n\nfunction _buildGuard(\n compiled: {\n preconditions: readonly unknown[]\n postconditions: readonly unknown[]\n sessionContracts: readonly unknown[]\n sandboxContracts: readonly unknown[]\n limits: OperationLimits\n defaultMode: string\n tools: Readonly<Record<string, Record<string, unknown>>>\n },\n policyVersion: string,\n options: YamlFactoryOptions,\n): Edictum {\n const effectiveMode = options.mode ?? compiled.defaultMode\n\n const allContracts = [\n ...compiled.preconditions,\n ...compiled.postconditions,\n ...compiled.sessionContracts,\n ...compiled.sandboxContracts,\n ]\n\n // Merge YAML tools with parameter tools (parameter wins on conflict)\n const mergedTools: Record<string, { side_effect?: string; idempotent?: boolean }> = {}\n for (const [name, cfg] of Object.entries(compiled.tools)) {\n mergedTools[name] = cfg as { side_effect?: string; idempotent?: boolean }\n }\n if (options.tools) {\n for (const [name, cfg] of Object.entries(options.tools)) {\n mergedTools[name] = cfg\n }\n }\n\n return new Edictum({\n environment: options.environment ?? 'production',\n mode: effectiveMode as 'enforce' | 'observe',\n limits: compiled.limits,\n tools: Object.keys(mergedTools).length > 0 ? mergedTools : undefined,\n contracts: allContracts as never[],\n auditSink: options.auditSink,\n redaction: options.redaction,\n backend: options.backend,\n policyVersion,\n onDeny: options.onDeny,\n onAllow: options.onAllow,\n successCheck: options.successCheck,\n principal: options.principal,\n principalResolver: options.principalResolver,\n approvalBackend: options.approvalBackend,\n })\n}\n","/** Bundle Composer — merge multiple parsed YAML bundles into one. */\n\nimport { EdictumConfigError } from '../errors.js'\n\n/** Records a contract that was replaced during composition. */\nexport interface CompositionOverride {\n readonly contractId: string\n readonly overriddenBy: string\n readonly originalSource: string\n}\n\n/** Records a contract added as an observe-mode copy (observe_alongside). */\nexport interface ObserveContract {\n readonly contractId: string\n readonly enforcedSource: string\n readonly observedSource: string\n}\n\n/** Report of what happened during composition. */\nexport interface CompositionReport {\n readonly overriddenContracts: readonly CompositionOverride[]\n readonly observeContracts: readonly ObserveContract[]\n}\n\n/** Result of composing multiple bundles. */\nexport interface ComposedBundle {\n readonly bundle: Record<string, unknown>\n readonly report: CompositionReport\n}\n\nfunction deepCopyBundle(data: Record<string, unknown>): Record<string, unknown> {\n return structuredClone(data)\n}\n\n/**\n * Merge multiple parsed bundle dicts left to right.\n *\n * Each entry is a tuple of [bundleData, sourceLabel]. Later layers\n * have higher priority.\n */\nexport function composeBundles(...bundles: [Record<string, unknown>, string][]): ComposedBundle {\n if (bundles.length === 0) {\n throw new Error('composeBundles() requires at least one bundle')\n }\n\n if (bundles.length === 1) {\n const entry = bundles[0] as [Record<string, unknown>, string]\n return {\n bundle: deepCopyBundle(entry[0]),\n report: { overriddenContracts: [], observeContracts: [] },\n }\n }\n\n const overrides: CompositionOverride[] = []\n const observes: ObserveContract[] = []\n\n const first = bundles[0] as [Record<string, unknown>, string]\n const merged = deepCopyBundle(first[0])\n const firstLabel = first[1]\n\n const contractSources = new Map<string, string>()\n for (const c of (merged.contracts ?? []) as Record<string, unknown>[]) {\n contractSources.set(c.id as string, firstLabel)\n }\n\n for (let i = 1; i < bundles.length; i++) {\n const entry = bundles[i] as [Record<string, unknown>, string]\n const [data, label] = entry\n const isObserveAlongside = Boolean(data.observe_alongside)\n\n if (isObserveAlongside) {\n mergeObserveAlongside(merged, data, label, contractSources, observes)\n } else {\n mergeStandard(merged, data, label, contractSources, overrides)\n }\n }\n\n return {\n bundle: merged,\n report: { overriddenContracts: overrides, observeContracts: observes },\n }\n}\n\nfunction mergeStandard(\n merged: Record<string, unknown>,\n layer: Record<string, unknown>,\n label: string,\n contractSources: Map<string, string>,\n overrides: CompositionOverride[],\n): void {\n if ('defaults' in layer) {\n const ld = layer.defaults as Record<string, unknown>\n const md = (merged.defaults ?? {}) as Record<string, unknown>\n if ('mode' in ld) md.mode = ld.mode\n if ('environment' in ld) md.environment = ld.environment\n merged.defaults = md\n }\n\n if ('limits' in layer) merged.limits = deepCopyBundle(layer.limits as Record<string, unknown>)\n\n if ('tools' in layer) {\n const mt = (merged.tools ?? {}) as Record<string, unknown>\n for (const [name, cfg] of Object.entries(layer.tools as Record<string, unknown>)) {\n mt[name] = { ...(cfg as Record<string, unknown>) }\n }\n merged.tools = mt\n }\n\n if ('metadata' in layer) {\n const mm = (merged.metadata ?? {}) as Record<string, unknown>\n for (const [k, v] of Object.entries(layer.metadata as Record<string, unknown>)) mm[k] = v\n merged.metadata = mm\n }\n\n if ('observability' in layer) {\n merged.observability = deepCopyBundle(layer.observability as Record<string, unknown>)\n }\n\n if ('contracts' in layer) {\n const existingById = new Map<string, number>()\n const mc = (merged.contracts ?? []) as Record<string, unknown>[]\n for (let j = 0; j < mc.length; j++) {\n const c = mc[j] as Record<string, unknown>\n existingById.set(c.id as string, j)\n }\n\n for (const contract of (layer.contracts ?? []) as Record<string, unknown>[]) {\n const cid = contract.id as string\n const newContract = deepCopyBundle(contract)\n\n if (existingById.has(cid)) {\n const idx = existingById.get(cid) as number\n overrides.push({\n contractId: cid,\n overriddenBy: label,\n originalSource: contractSources.get(cid) ?? 'unknown',\n })\n mc[idx] = newContract\n } else {\n mc.push(newContract)\n existingById.set(cid, mc.length - 1)\n }\n contractSources.set(cid, label)\n }\n merged.contracts = mc\n }\n}\n\nfunction mergeObserveAlongside(\n merged: Record<string, unknown>,\n layer: Record<string, unknown>,\n label: string,\n contractSources: Map<string, string>,\n observes: ObserveContract[],\n): void {\n const mc = (merged.contracts ?? []) as Record<string, unknown>[]\n\n for (const contract of (layer.contracts ?? []) as Record<string, unknown>[]) {\n const cid = contract.id as string\n const observeId = `${cid}:candidate`\n\n // Check for ID collisions — the generated observe ID must not clash\n // with any existing contract in the merged bundle.\n const existingIds = new Set((mc as Record<string, unknown>[]).map((c) => c.id as string))\n if (existingIds.has(observeId)) {\n throw new EdictumConfigError(\n `observe_alongside collision: generated ID \"${observeId}\" already exists in the bundle. ` +\n `Rename the conflicting contract or use a different ID for \"${cid}\".`,\n )\n }\n\n const observeContract = deepCopyBundle(contract)\n observeContract.id = observeId\n observeContract.mode = 'observe'\n observeContract._observe = true\n\n mc.push(observeContract)\n observes.push({\n contractId: cid,\n enforcedSource: contractSources.get(cid) ?? '',\n observedSource: label,\n })\n }\n merged.contracts = mc\n\n if ('tools' in layer) {\n const mt = (merged.tools ?? {}) as Record<string, unknown>\n for (const [name, cfg] of Object.entries(layer.tools as Record<string, unknown>)) {\n mt[name] = { ...(cfg as Record<string, unknown>) }\n }\n merged.tools = mt\n }\n\n if ('metadata' in layer) {\n const mm = (merged.metadata ?? {}) as Record<string, unknown>\n for (const [k, v] of Object.entries(layer.metadata as Record<string, unknown>)) mm[k] = v\n merged.metadata = mm\n }\n}\n","/** Built-in operators for YAML condition evaluation. */\n\n/** Cap regex input to prevent catastrophic backtracking DoS. */\nexport const MAX_REGEX_INPUT = 10_000\n\n// ---------------------------------------------------------------------------\n// Operator implementations\n// ---------------------------------------------------------------------------\n\nfunction opEquals(fieldValue: unknown, opValue: unknown): boolean {\n return fieldValue === opValue\n}\n\nfunction opNotEquals(fieldValue: unknown, opValue: unknown): boolean {\n return fieldValue !== opValue\n}\n\nfunction opIn(fieldValue: unknown, opValue: unknown[]): boolean {\n return opValue.includes(fieldValue)\n}\n\nfunction opNotIn(fieldValue: unknown, opValue: unknown[]): boolean {\n return !opValue.includes(fieldValue)\n}\n\nfunction opContains(fieldValue: unknown, opValue: string): boolean {\n if (typeof fieldValue !== 'string') throw new TypeError()\n return fieldValue.includes(opValue)\n}\n\nfunction opContainsAny(fieldValue: unknown, opValue: string[]): boolean {\n if (typeof fieldValue !== 'string') throw new TypeError()\n return opValue.some((v) => fieldValue.includes(v))\n}\n\nfunction opStartsWith(fieldValue: unknown, opValue: string): boolean {\n if (typeof fieldValue !== 'string') throw new TypeError()\n return fieldValue.startsWith(opValue)\n}\n\nfunction opEndsWith(fieldValue: unknown, opValue: string): boolean {\n if (typeof fieldValue !== 'string') throw new TypeError()\n return fieldValue.endsWith(opValue)\n}\n\nfunction opMatches(fieldValue: unknown, opValue: string | RegExp): boolean {\n if (typeof fieldValue !== 'string') throw new TypeError()\n const truncated = fieldValue.slice(0, MAX_REGEX_INPUT)\n if (opValue instanceof RegExp) {\n return opValue.test(truncated)\n }\n return new RegExp(opValue).test(truncated)\n}\n\nfunction opMatchesAny(fieldValue: unknown, opValue: Array<string | RegExp>): boolean {\n if (typeof fieldValue !== 'string') throw new TypeError()\n const truncated = fieldValue.slice(0, MAX_REGEX_INPUT)\n return opValue.some((p) =>\n p instanceof RegExp ? p.test(truncated) : new RegExp(p).test(truncated),\n )\n}\n\nfunction opGt(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== 'number') throw new TypeError()\n return fieldValue > opValue\n}\n\nfunction opGte(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== 'number') throw new TypeError()\n return fieldValue >= opValue\n}\n\nfunction opLt(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== 'number') throw new TypeError()\n return fieldValue < opValue\n}\n\nfunction opLte(fieldValue: unknown, opValue: number): boolean {\n if (typeof fieldValue !== 'number') throw new TypeError()\n return fieldValue <= opValue\n}\n\n// ---------------------------------------------------------------------------\n// Operator dispatch table\n// ---------------------------------------------------------------------------\n\nexport type OperatorFn = (fieldValue: unknown, opValue: unknown) => boolean\n\nexport const OPERATORS: Readonly<Record<string, OperatorFn>> = {\n equals: opEquals,\n not_equals: opNotEquals,\n in: opIn as OperatorFn,\n not_in: opNotIn as OperatorFn,\n contains: opContains as OperatorFn,\n contains_any: opContainsAny as OperatorFn,\n starts_with: opStartsWith as OperatorFn,\n ends_with: opEndsWith as OperatorFn,\n matches: opMatches as OperatorFn,\n matches_any: opMatchesAny as OperatorFn,\n gt: opGt as OperatorFn,\n gte: opGte as OperatorFn,\n lt: opLt as OperatorFn,\n lte: opLte as OperatorFn,\n}\n\n/** All built-in operator names (including \"exists\" which is special-cased). */\nexport const BUILTIN_OPERATOR_NAMES: ReadonlySet<string> = new Set([\n ...Object.keys(OPERATORS),\n 'exists',\n])\n","/** Selector resolution — map YAML selector paths to ToolEnvelope values. */\n\nimport type { ToolEnvelope } from '../envelope.js'\nimport type { CustomSelector } from './evaluator.js'\n\n// ---------------------------------------------------------------------------\n// Sentinel for \"field not found\"\n// ---------------------------------------------------------------------------\n\nconst _MISSING: unique symbol = Symbol('MISSING')\nexport type Missing = typeof _MISSING\nexport { _MISSING }\n\n// ---------------------------------------------------------------------------\n// Built-in selector prefixes — custom selectors must not use these\n// ---------------------------------------------------------------------------\n\nexport const BUILTIN_SELECTOR_PREFIXES: ReadonlySet<string> = new Set([\n 'environment',\n 'tool',\n 'args',\n 'principal',\n 'output',\n 'env',\n 'metadata',\n])\n\n// ---------------------------------------------------------------------------\n// Selector resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a dotted selector path to a value from the envelope.\n * Returns `_MISSING` if the field is not found at any level.\n *\n * NOTE: ToolEnvelope uses camelCase (toolName, userId, serviceId, orgId,\n * ticketRef) but YAML selectors use snake_case (tool.name, principal.user_id).\n * This function maps between the two.\n */\nexport function resolveSelector(\n selector: string,\n envelope: ToolEnvelope,\n outputText?: string | null,\n customSelectors?: Readonly<Record<string, CustomSelector>> | null,\n): unknown {\n if (selector === 'environment') return envelope.environment\n if (selector === 'tool.name') return envelope.toolName\n\n if (selector.startsWith('args.')) {\n return resolveNested(selector.slice(5), envelope.args as Record<string, unknown>)\n }\n\n if (selector.startsWith('principal.')) {\n if (envelope.principal == null) return _MISSING\n const rest = selector.slice(10)\n // Map YAML snake_case selectors to TS camelCase properties\n if (rest === 'user_id') return envelope.principal.userId\n if (rest === 'service_id') return envelope.principal.serviceId\n if (rest === 'org_id') return envelope.principal.orgId\n if (rest === 'role') return envelope.principal.role\n if (rest === 'ticket_ref') return envelope.principal.ticketRef\n if (rest.startsWith('claims.')) {\n return resolveNested(rest.slice(7), envelope.principal.claims as Record<string, unknown>)\n }\n return _MISSING\n }\n\n if (selector === 'output.text') {\n return outputText == null ? _MISSING : outputText\n }\n\n // SECURITY NOTE (Python parity): env.* selector intentionally reads from\n // process.env, matching Python's os.environ.get(). This is by design — YAML\n // contracts use env.* to gate behavior on environment variables (e.g.,\n // env.EDICTUM_MODE). The message template expansion layer handles secret\n // redaction. Bundle authors control which env vars are referenced; untrusted\n // YAML bundles should not be loaded without review.\n if (selector.startsWith('env.')) {\n const varName = selector.slice(4)\n const raw = process.env[varName]\n if (raw == null) return _MISSING\n return coerceEnvValue(raw)\n }\n\n if (selector.startsWith('metadata.')) {\n return resolveNested(selector.slice(9), envelope.metadata as Record<string, unknown>)\n }\n\n // Custom selectors: match prefix before first dot\n if (customSelectors) {\n const dotPos = selector.indexOf('.')\n if (dotPos > 0) {\n const prefix = selector.slice(0, dotPos)\n if (Object.hasOwn(customSelectors, prefix)) {\n const resolver = customSelectors[prefix] as CustomSelector\n const data = resolver(envelope)\n const rest = selector.slice(dotPos + 1)\n return resolveNested(rest, data)\n }\n }\n }\n\n return _MISSING\n}\n\n// ---------------------------------------------------------------------------\n// Nested path resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a dotted path through nested dicts.\n * Returns `_MISSING` if any intermediate key is absent or not a dict.\n */\nexport function resolveNested(path: string, data: unknown): unknown {\n const parts = path.split('.')\n let current = data\n for (const part of parts) {\n if (current == null || typeof current !== 'object') return _MISSING\n const obj = current as Record<string, unknown>\n if (!Object.hasOwn(obj, part)) return _MISSING\n current = obj[part]\n }\n return current\n}\n\n// ---------------------------------------------------------------------------\n// Env value coercion\n// ---------------------------------------------------------------------------\n\n/** Coerce an env var string to a typed value for operator comparison. */\nexport function coerceEnvValue(raw: string): string | boolean | number {\n const low = raw.toLowerCase()\n if (low === 'true') return true\n if (low === 'false') return false\n const asInt = parseInt(raw, 10)\n if (!isNaN(asInt) && String(asInt) === raw) return asInt\n const asFloat = parseFloat(raw)\n if (!isNaN(asFloat) && String(asFloat) === raw) return asFloat\n return raw\n}\n","/** Condition Evaluator — resolve selectors and apply operators against ToolEnvelope. */\n\nimport type { ToolEnvelope } from '../envelope.js'\nimport { OPERATORS, BUILTIN_OPERATOR_NAMES } from './operators.js'\nimport { _MISSING, resolveSelector } from './selectors.js'\n\n// Re-export for external consumers\nexport { BUILTIN_OPERATOR_NAMES }\nexport { MAX_REGEX_INPUT } from './operators.js'\nexport { _MISSING, BUILTIN_SELECTOR_PREFIXES, resolveSelector } from './selectors.js'\nexport type { Missing } from './selectors.js'\n// Aliased re-exports for backward-compatible names\nexport { resolveNested as _resolveNested, coerceEnvValue as _coerceEnvValue } from './selectors.js'\n\n// ---------------------------------------------------------------------------\n// PolicyError — sentinel for type mismatches (fail-closed)\n// ---------------------------------------------------------------------------\n\n/**\n * Sentinel indicating a type mismatch or evaluation error.\n *\n * Converts to `true` conceptually — errors trigger the contract (fail-closed).\n * Callers should treat PolicyError as \"condition matched\" and apply\n * deny/warn + policyError flag.\n */\nexport class PolicyError {\n readonly message: string\n constructor(message: string) {\n this.message = message\n }\n}\n\n// ---------------------------------------------------------------------------\n// Custom extension types\n// ---------------------------------------------------------------------------\n\nexport type CustomOperator = (fieldValue: unknown, opValue: unknown) => boolean\nexport type CustomSelector = (envelope: ToolEnvelope) => Record<string, unknown>\n\nexport interface EvaluateOptions {\n readonly customOperators?: Readonly<Record<string, CustomOperator>> | null\n readonly customSelectors?: Readonly<Record<string, CustomSelector>> | null\n}\n\n// ---------------------------------------------------------------------------\n// Main entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate a boolean expression tree against an envelope.\n *\n * Returns `true` if the expression matches, `false` if not.\n * Returns a `PolicyError` if a type mismatch or evaluation error occurs\n * (caller should treat as deny/warn + policyError).\n *\n * Missing fields always evaluate to `false` (contract doesn't fire).\n */\nexport function evaluateExpression(\n expr: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText?: string | null,\n options?: EvaluateOptions,\n): boolean | PolicyError {\n const customOps = options?.customOperators ?? null\n const customSels = options?.customSelectors ?? null\n\n if ('all' in expr) {\n return _evalAll(\n expr.all as Record<string, unknown>[],\n envelope,\n outputText,\n customOps,\n customSels,\n )\n }\n if ('any' in expr) {\n return _evalAny(\n expr.any as Record<string, unknown>[],\n envelope,\n outputText,\n customOps,\n customSels,\n )\n }\n if ('not' in expr) {\n return _evalNot(\n expr.not as Record<string, unknown>,\n envelope,\n outputText,\n customOps,\n customSels,\n )\n }\n\n // Leaf node: exactly one selector key (schema enforces single-key leaves).\n // Guard: if a malformed leaf has multiple keys, fail-closed with PolicyError\n // rather than silently dropping extra keys. Python takes next(iter(leaf))\n // which also ignores extras — this is a strictness improvement.\n const leafKeys = Object.keys(expr)\n if (leafKeys.length !== 1) {\n return new PolicyError(\n `Leaf expression must have exactly one selector key, got ${leafKeys.length}: [${leafKeys.join(', ')}]`,\n )\n }\n return _evalLeaf(expr, envelope, outputText, customOps, customSels)\n}\n\n// ---------------------------------------------------------------------------\n// Boolean AST nodes\n// ---------------------------------------------------------------------------\n\nfunction _evalAll(\n exprs: Record<string, unknown>[],\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n for (const expr of exprs) {\n const result = evaluateExpression(expr, envelope, outputText, {\n customOperators: customOps,\n customSelectors: customSels,\n })\n if (result instanceof PolicyError) return result\n if (!result) return false\n }\n return true\n}\n\nfunction _evalAny(\n exprs: Record<string, unknown>[],\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n for (const expr of exprs) {\n const result = evaluateExpression(expr, envelope, outputText, {\n customOperators: customOps,\n customSelectors: customSels,\n })\n if (result instanceof PolicyError) return result\n if (result) return true\n }\n return false\n}\n\nfunction _evalNot(\n expr: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n const result = evaluateExpression(expr, envelope, outputText, {\n customOperators: customOps,\n customSelectors: customSels,\n })\n if (result instanceof PolicyError) return result\n return !result\n}\n\nfunction _evalLeaf(\n leaf: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): boolean | PolicyError {\n const selector = Object.keys(leaf)[0] as string\n const operatorBlock = leaf[selector] as Record<string, unknown>\n const value = resolveSelector(selector, envelope, outputText, customSels)\n const opName = Object.keys(operatorBlock)[0] as string\n const opValue = operatorBlock[opName]\n return _applyOperator(opName, value, opValue, selector, customOps)\n}\n\n// ---------------------------------------------------------------------------\n// Operator application\n// ---------------------------------------------------------------------------\n\n/** Apply a single operator to a resolved field value. */\nfunction _applyOperator(\n op: string,\n fieldValue: unknown,\n opValue: unknown,\n selector: string,\n customOperators: Readonly<Record<string, CustomOperator>> | null,\n): boolean | PolicyError {\n // exists is special — works on _MISSING\n if (op === 'exists') {\n const isPresent = fieldValue !== _MISSING && fieldValue != null\n return isPresent === opValue\n }\n\n // All other operators: missing field -> false\n if (fieldValue === _MISSING || fieldValue == null) return false\n\n try {\n if (Object.hasOwn(OPERATORS, op))\n return (OPERATORS[op] as (fv: unknown, ov: unknown) => boolean)(fieldValue, opValue)\n if (customOperators && Object.hasOwn(customOperators, op)) {\n return Boolean((customOperators[op] as CustomOperator)(fieldValue, opValue))\n }\n return new PolicyError(`Unknown operator: '${op}'`)\n } catch {\n return new PolicyError(\n `Type mismatch: operator '${op}' cannot be applied to ` +\n `selector '${selector}' value ${typeof fieldValue}`,\n )\n }\n}\n","/** Compiler utilities — validation, regex precompilation, message expansion. */\n\nimport { EdictumConfigError } from '../errors.js'\nimport { RedactionPolicy } from '../redaction.js'\nimport type { ToolEnvelope } from '../envelope.js'\nimport {\n BUILTIN_OPERATOR_NAMES,\n _MISSING,\n resolveSelector,\n type CustomSelector,\n} from './evaluator.js'\n\n// ---------------------------------------------------------------------------\n// Placeholder expansion\n// ---------------------------------------------------------------------------\n\nconst _PLACEHOLDER_RE = /\\{([^}]+)\\}/g\nconst _PLACEHOLDER_CAP = 200\n\n/**\n * Expand {placeholder} tokens in a message template.\n *\n * Missing placeholders are kept as-is. Each expansion is capped at 200 chars.\n * Values that look like secrets are redacted.\n */\nexport function expandMessage(\n template: string,\n envelope: ToolEnvelope,\n outputText?: string | null,\n customSelectors?: Readonly<Record<string, CustomSelector>> | null,\n): string {\n const redaction = new RedactionPolicy()\n\n return template.replace(_PLACEHOLDER_RE, (match, selectorRaw: string) => {\n const value = resolveSelector(selectorRaw, envelope, outputText, customSelectors)\n if (value === _MISSING || value == null) return match\n let text = String(value)\n if (redaction._looksLikeSecret(text)) text = '[REDACTED]'\n if (text.length > _PLACEHOLDER_CAP) text = text.slice(0, _PLACEHOLDER_CAP - 3) + '...'\n return text\n })\n}\n\n// ---------------------------------------------------------------------------\n// Operator validation\n// ---------------------------------------------------------------------------\n\n/** Validate that all operators used in the bundle are known (built-in or custom). */\nexport function validateOperators(\n bundle: Record<string, unknown>,\n customOperators: Readonly<Record<string, unknown>> | null,\n): void {\n const known = new Set([...BUILTIN_OPERATOR_NAMES, ...Object.keys(customOperators ?? {})])\n const contracts = (bundle.contracts ?? []) as Record<string, unknown>[]\n for (const contract of contracts) {\n const when = contract.when as Record<string, unknown> | undefined\n if (when) {\n _validateExpressionOperators(when, known, contract.id as string)\n }\n }\n}\n\nfunction _validateExpressionOperators(\n expr: unknown,\n known: ReadonlySet<string>,\n contractId: string,\n): void {\n if (expr == null || typeof expr !== 'object') return\n const e = expr as Record<string, unknown>\n\n if ('all' in e) {\n for (const sub of e.all as Record<string, unknown>[]) {\n _validateExpressionOperators(sub, known, contractId)\n }\n return\n }\n if ('any' in e) {\n for (const sub of e.any as Record<string, unknown>[]) {\n _validateExpressionOperators(sub, known, contractId)\n }\n return\n }\n if ('not' in e) {\n _validateExpressionOperators(e.not, known, contractId)\n return\n }\n\n // Leaf node: selector -> operator\n for (const [, operator] of Object.entries(e)) {\n if (operator != null && typeof operator === 'object') {\n for (const opName of Object.keys(operator as Record<string, unknown>)) {\n if (!known.has(opName)) {\n throw new EdictumConfigError(`Contract '${contractId}': unknown operator '${opName}'`)\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Regex precompilation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively walk an expression tree and compile regex patterns.\n *\n * Replaces string values under `matches` and `matches_any` with\n * pre-compiled RegExp objects so the evaluator never recompiles on every call.\n */\nexport function precompileRegexes(expr: unknown): unknown {\n if (expr == null || typeof expr !== 'object') return expr\n const e = expr as Record<string, unknown>\n\n if ('all' in e) {\n return { all: (e.all as unknown[]).map(precompileRegexes) }\n }\n if ('any' in e) {\n return { any: (e.any as unknown[]).map(precompileRegexes) }\n }\n if ('not' in e) {\n return { not: precompileRegexes(e.not) }\n }\n\n // Leaf node: selector -> operator\n const compiled: Record<string, unknown> = {}\n for (const [selector, operator] of Object.entries(e)) {\n if (operator == null || typeof operator !== 'object') {\n compiled[selector] = operator\n continue\n }\n const newOp = { ...(operator as Record<string, unknown>) }\n if ('matches' in newOp && typeof newOp.matches === 'string') {\n newOp.matches = new RegExp(newOp.matches)\n }\n if ('matches_any' in newOp && Array.isArray(newOp.matches_any)) {\n newOp.matches_any = (newOp.matches_any as string[]).map((p) =>\n typeof p === 'string' ? new RegExp(p) : p,\n )\n }\n compiled[selector] = newOp\n }\n return compiled\n}\n\n// ---------------------------------------------------------------------------\n// Output pattern extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Walk an expression tree and collect regex patterns from output.text leaves.\n *\n * Returns a flat list of compiled RegExp objects found under `matches` or\n * `matches_any` operators where the selector is `output.text`.\n * By the time this runs, `precompileRegexes` has already converted strings.\n */\nexport function extractOutputPatterns(expr: unknown): RegExp[] {\n if (expr == null || typeof expr !== 'object') return []\n const e = expr as Record<string, unknown>\n\n if ('all' in e) {\n const patterns: RegExp[] = []\n for (const sub of e.all as unknown[]) {\n patterns.push(...extractOutputPatterns(sub))\n }\n return patterns\n }\n if ('any' in e) {\n const patterns: RegExp[] = []\n for (const sub of e.any as unknown[]) {\n patterns.push(...extractOutputPatterns(sub))\n }\n return patterns\n }\n if ('not' in e) {\n return extractOutputPatterns(e.not)\n }\n\n // Leaf node\n const collected: RegExp[] = []\n for (const [selector, operator] of Object.entries(e)) {\n if (selector !== 'output.text' || operator == null || typeof operator !== 'object') continue\n const op = operator as Record<string, unknown>\n if ('matches' in op && op.matches instanceof RegExp) {\n collected.push(op.matches)\n }\n if ('matches_any' in op && Array.isArray(op.matches_any)) {\n for (const p of op.matches_any) {\n if (p instanceof RegExp) collected.push(p)\n }\n }\n }\n return collected\n}\n","/** Contract compilation — compile individual YAML contracts into callable objects. */\n\nimport { Verdict } from '../contracts.js'\nimport type { ToolEnvelope } from '../envelope.js'\nimport { EdictumConfigError } from '../errors.js'\nimport type { OperationLimits } from '../limits.js'\nimport type { Session } from '../session.js'\nimport {\n evaluateExpression,\n PolicyError,\n type CustomOperator,\n type CustomSelector,\n} from './evaluator.js'\nimport { expandMessage, extractOutputPatterns, precompileRegexes } from './compiler-utils.js'\n\n/** Shared evaluation logic for pre/post check functions. */\nfunction _evalAndVerdict(\n whenExpr: Record<string, unknown>,\n envelope: ToolEnvelope,\n outputText: string | null | undefined,\n messageTemplate: string,\n tags: string[],\n thenMetadata: Record<string, unknown>,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): Verdict {\n try {\n const result = evaluateExpression(whenExpr, envelope, outputText, {\n customOperators: customOps,\n customSelectors: customSels,\n })\n if (result instanceof PolicyError) {\n const msg = expandMessage(messageTemplate, envelope, outputText, customSels)\n return Verdict.fail(msg, { tags, policyError: true, ...thenMetadata })\n }\n if (result) {\n const msg = expandMessage(messageTemplate, envelope, outputText, customSels)\n return Verdict.fail(msg, { tags, ...thenMetadata })\n }\n return Verdict.pass_()\n } catch (exc) {\n const msg = expandMessage(messageTemplate, envelope, outputText, customSels)\n return Verdict.fail(msg, { tags, policyError: true, errorDetail: String(exc), ...thenMetadata })\n }\n}\n\n/** Stamp _edictum_observe on the result if the contract is in observe mode. */\nfunction _maybeObserve(result: Record<string, unknown>, contract: Record<string, unknown>): void {\n if (contract._observe === true || contract._shadow === true) result._edictum_observe = true\n}\n\n// ---------------------------------------------------------------------------\n// Pre-contract compilation\n// ---------------------------------------------------------------------------\n\nexport function compilePre(\n contract: Record<string, unknown>,\n mode: string,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): Record<string, unknown> {\n const contractId = contract.id as string\n const tool = contract.tool as string\n const whenExpr = precompileRegexes(contract.when) as Record<string, unknown>\n const then = contract.then as Record<string, unknown>\n const msgTpl = then.message as string\n const tags = (then.tags ?? []) as string[]\n const meta = (then.metadata ?? {}) as Record<string, unknown>\n\n const check = (envelope: ToolEnvelope): Verdict =>\n _evalAndVerdict(whenExpr, envelope, undefined, msgTpl, tags, meta, customOps, customSels)\n\n const result: Record<string, unknown> = {\n check,\n name: contractId,\n tool,\n type: 'precondition',\n mode: mode as 'enforce' | 'observe',\n _edictum_type: 'precondition',\n _edictum_tool: tool,\n _edictum_when: null,\n _edictum_mode: mode,\n _edictum_id: contractId,\n _edictum_source: 'yaml_precondition',\n _edictum_effect: (then.effect as string) ?? 'deny',\n _edictum_timeout: (then.timeout as number) ?? 300,\n _edictum_timeout_effect: (then.timeout_effect as string) ?? 'deny',\n }\n _maybeObserve(result, contract)\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Post-contract compilation\n// ---------------------------------------------------------------------------\n\nexport function compilePost(\n contract: Record<string, unknown>,\n mode: string,\n customOps: Readonly<Record<string, CustomOperator>> | null,\n customSels: Readonly<Record<string, CustomSelector>> | null,\n): Record<string, unknown> {\n const contractId = contract.id as string\n const tool = contract.tool as string\n const whenExpr = precompileRegexes(contract.when) as Record<string, unknown>\n const then = contract.then as Record<string, unknown>\n const msgTpl = then.message as string\n const tags = (then.tags ?? []) as string[]\n const meta = (then.metadata ?? {}) as Record<string, unknown>\n\n const check = (envelope: ToolEnvelope, response: unknown): Verdict => {\n const outputText = response != null ? String(response) : undefined\n return _evalAndVerdict(\n whenExpr,\n envelope,\n outputText,\n msgTpl,\n tags,\n meta,\n customOps,\n customSels,\n )\n }\n\n const effectValue = (then.effect as string) ?? 'warn'\n const result: Record<string, unknown> = {\n check,\n name: contractId,\n tool,\n type: 'postcondition',\n mode: mode as 'enforce' | 'observe',\n effect: effectValue,\n _edictum_type: 'postcondition',\n _edictum_tool: tool,\n _edictum_when: null,\n _edictum_mode: mode,\n _edictum_id: contractId,\n _edictum_source: 'yaml_postcondition',\n _edictum_effect: effectValue,\n _edictum_redact_patterns: extractOutputPatterns(whenExpr),\n }\n _maybeObserve(result, contract)\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Session contract compilation\n// ---------------------------------------------------------------------------\n\nexport function compileSession(\n contract: Record<string, unknown>,\n mode: string,\n limits: OperationLimits,\n): Record<string, unknown> {\n const contractId = contract.id as string\n const then = contract.then as Record<string, unknown>\n const messageTemplate = then.message as string\n const tags = (then.tags ?? []) as string[]\n const thenMetadata = (then.metadata ?? {}) as Record<string, unknown>\n const capturedLimits = { ...limits }\n\n const check = async (session: Session): Promise<Verdict> => {\n const execCount = await session.executionCount()\n if (execCount >= capturedLimits.maxToolCalls) {\n return Verdict.fail(messageTemplate, { tags, ...thenMetadata })\n }\n const attemptCount = await session.attemptCount()\n if (attemptCount >= capturedLimits.maxAttempts) {\n return Verdict.fail(messageTemplate, { tags, ...thenMetadata })\n }\n return Verdict.pass_()\n }\n\n const result: Record<string, unknown> = {\n check,\n name: contractId,\n type: 'session_contract',\n _edictum_type: 'session_contract',\n _edictum_mode: mode,\n _edictum_id: contractId,\n _edictum_message: messageTemplate,\n _edictum_tags: tags,\n _edictum_then_metadata: thenMetadata,\n _edictum_source: 'yaml_session',\n }\n if (contract._observe === true || contract._shadow === true) {\n result._edictum_observe = true\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Session limits merging\n// ---------------------------------------------------------------------------\n\n/**\n * Merge session contract limits into existing OperationLimits.\n * Picks the more restrictive value (lower) for each limit.\n */\nexport function mergeSessionLimits(\n contract: Record<string, unknown>,\n existing: OperationLimits,\n): OperationLimits {\n const sessionLimits = contract.limits as Record<string, unknown>\n let maxToolCalls = existing.maxToolCalls\n let maxAttempts = existing.maxAttempts\n const maxCallsPerTool: Record<string, number> = { ...existing.maxCallsPerTool }\n\n if ('max_tool_calls' in sessionLimits) {\n const raw = sessionLimits.max_tool_calls\n if (typeof raw !== 'number' || !Number.isFinite(raw)) {\n throw new EdictumConfigError(\n `Session limit max_tool_calls must be a finite number, got: ${String(raw)}`,\n )\n }\n maxToolCalls = Math.min(maxToolCalls, raw)\n }\n if ('max_attempts' in sessionLimits) {\n const raw = sessionLimits.max_attempts\n if (typeof raw !== 'number' || !Number.isFinite(raw)) {\n throw new EdictumConfigError(\n `Session limit max_attempts must be a finite number, got: ${String(raw)}`,\n )\n }\n maxAttempts = Math.min(maxAttempts, raw)\n }\n if ('max_calls_per_tool' in sessionLimits) {\n const perTool = sessionLimits.max_calls_per_tool as Record<string, unknown>\n for (const [tool, limit] of Object.entries(perTool)) {\n if (typeof limit !== 'number' || !Number.isFinite(limit)) {\n throw new EdictumConfigError(\n `Session limit max_calls_per_tool['${tool}'] must be a finite number, got: ${String(limit)}`,\n )\n }\n if (Object.hasOwn(maxCallsPerTool, tool)) {\n maxCallsPerTool[tool] = Math.min(maxCallsPerTool[tool] as number, limit)\n } else {\n maxCallsPerTool[tool] = limit\n }\n }\n }\n return { maxAttempts, maxToolCalls, maxCallsPerTool }\n}\n","/**\n * Minimal Python fnmatch.fnmatch() port for glob pattern matching.\n *\n * Used by Edictum for contract tool filtering and hook registration.\n */\n\n/**\n * Match a name against a glob pattern (fnmatch-style).\n *\n * Supports: `*` (any sequence), `?` (any single char), literal match.\n * Does NOT support `[...]` character classes (not used by edictum contracts).\n *\n * Input capped at 10,000 characters to prevent regex DoS.\n */\nexport function fnmatch(name: string, pattern: string): boolean {\n if (pattern === '*') return true\n if (!pattern.includes('*') && !pattern.includes('?')) {\n return name === pattern\n }\n\n // Cap input length for regex DoS prevention\n const safeName = name.length > 10_000 ? name.slice(0, 10_000) : name\n const safePattern = pattern.length > 10_000 ? pattern.slice(0, 10_000) : pattern\n\n // Convert glob to regex: escape regex chars, then replace glob wildcards\n let regex = ''\n for (let i = 0; i < safePattern.length; i++) {\n const ch = safePattern[i] ?? ''\n if (ch === '*') {\n regex += '.*'\n } else if (ch === '?') {\n regex += '.'\n } else if ('.+^${}()|[]\\\\'.includes(ch)) {\n regex += '\\\\' + ch\n } else {\n regex += ch\n }\n }\n\n return new RegExp('^' + regex + '$').test(safeName)\n}\n","/** Cross-platform path resolution that matches Python's os.path.realpath(). */\n\nimport { realpathSync } from 'node:fs'\nimport { resolve as pathResolve, sep as pathSep, join as pathJoin } from 'node:path'\n\n/**\n * Resolve a path like Python's os.path.realpath() — resolve symlinks on\n * existing path components even when the full path doesn't exist.\n *\n * Node's fs.realpathSync() throws ENOENT if the path doesn't exist,\n * whereas Python's os.path.realpath() resolves as much as it can.\n * This matters on macOS where /home/ → /System/Volumes/Data/home/:\n * - Python: realpath(\"/home/user/file.txt\") → \"/System/Volumes/Data/home/user/file.txt\"\n * - Node: realpathSync(\"/home/user/file.txt\") → throws → fallback loses symlink info\n *\n * This function walks up the directory tree to find the deepest existing\n * ancestor, resolves its symlinks, then appends the remaining components.\n *\n * Security: only ENOENT triggers the walk-up fallback. EACCES (permission\n * denied) and ELOOP (circular symlink) return the normalized path without\n * partial resolution — fail closed when the true target is unknowable.\n */\nexport function resolvePath(p: string): string {\n // Strip null bytes before any path operation. A path like\n // \"/allowed/path\\x00/../etc/passwd\" would pass prefix checks\n // (starts with /allowed/path) but C-based tools truncate at \\0,\n // reading /allowed/path instead. This is a sandbox escape vector.\n const cleaned = p.replace(/\\0/g, '')\n const resolved = pathResolve(cleaned)\n try {\n return realpathSync(resolved)\n } catch (err: unknown) {\n // Only apply the walk-up fallback for ENOENT (path doesn't exist yet).\n // For EACCES, ELOOP, or any other error, return the normalized path\n // without attempting partial resolution — we cannot safely determine\n // the true target and must fail closed.\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n return resolved\n }\n // Walk up to find deepest existing ancestor and resolve its symlinks\n const parts = resolved.split(pathSep)\n for (let i = parts.length - 1; i > 0; i--) {\n const prefix = parts.slice(0, i).join(pathSep) || '/'\n try {\n const realPrefix = realpathSync(prefix)\n const rest = parts.slice(i).join(pathSep)\n return pathJoin(realPrefix, rest)\n } catch (innerErr: unknown) {\n // Only continue walk-up for ENOENT (ancestor doesn't exist).\n // For EACCES/ELOOP on an ancestor, bail out and return the\n // normalized path — we cannot safely determine whether the\n // ancestor is a symlink pointing outside the boundary.\n if ((innerErr as NodeJS.ErrnoException).code !== 'ENOENT') {\n return resolved\n }\n continue\n }\n }\n return resolved\n }\n}\n","/** Sandbox contract compiler — extract/classify tool call resources and compile sandbox contracts. */\n\nimport type { ToolEnvelope } from '../envelope.js'\nimport { fnmatch } from '../fnmatch.js'\nimport { resolvePath } from './resolve-path.js'\n\n// ---------------------------------------------------------------------------\n// Shell tokenization\n// ---------------------------------------------------------------------------\n\n/** Pattern for shell redirection operators at token start. */\nconst _REDIRECT_PREFIX_RE = /^(?:\\d*>>|>>|\\d*>|>|<<|<)/\n\n/**\n * Shell command separators and metacharacters that allow chaining\n * multiple commands. If any of these appear in a raw command string,\n * the command is unsafe — the shell would execute multiple commands.\n *\n * Covers: ; | && || \\n \\r $() backtick ${} <()\n */\nconst _SHELL_SEPARATOR_RE = /[;|&\\n\\r`]|\\$\\(|\\$\\{|<\\(/\n\n/**\n * Shell-aware tokenization of a command string.\n *\n * Handles single/double quotes. Strips shell redirection operators from\n * token prefixes so paths after redirects (e.g. >/etc/passwd) are exposed.\n * Falls back to basic split with quote stripping on parse error.\n */\nexport function tokenizeCommand(cmd: string): string[] {\n const rawTokens = _shlexSplit(cmd)\n\n const tokens: string[] = []\n for (const t of rawTokens) {\n const stripped = t.replace(_REDIRECT_PREFIX_RE, '')\n if (stripped) tokens.push(stripped)\n }\n return tokens\n}\n\n/** Minimal shlex.split() port — handle single/double quotes. */\nfunction _shlexSplit(s: string): string[] {\n const tokens: string[] = []\n let current = ''\n let inSingle = false\n let inDouble = false\n let i = 0\n\n try {\n while (i < s.length) {\n const ch = s.charAt(i)\n if (inSingle) {\n if (ch === \"'\") {\n inSingle = false\n } else {\n current += ch\n }\n } else if (inDouble) {\n if (ch === '\\\\' && i + 1 < s.length) {\n // Backslash escaping inside double quotes: \\\", \\\\, \\$, \\`, \\newline\n const next = s.charAt(i + 1)\n if (next === '\"' || next === '\\\\' || next === '$' || next === '`' || next === '\\n') {\n current += next\n i++\n } else {\n // Literal backslash for other characters (POSIX behavior)\n current += ch\n }\n } else if (ch === '\"') {\n inDouble = false\n } else {\n current += ch\n }\n } else if (ch === \"'\") {\n inSingle = true\n } else if (ch === '\"') {\n inDouble = true\n } else if (ch === ' ' || ch === '\\t') {\n if (current) {\n tokens.push(current)\n current = ''\n }\n } else {\n current += ch\n }\n i++\n }\n // Unclosed quotes — fall back\n if (inSingle || inDouble) {\n return s\n .split(/\\s+/)\n .filter(Boolean)\n .map((t) => t.replace(/^['\"]|['\"]$/g, ''))\n }\n if (current) tokens.push(current)\n return tokens\n } catch {\n return s\n .split(/\\s+/)\n .filter(Boolean)\n .map((t) => t.replace(/^['\"]|['\"]$/g, ''))\n }\n}\n\n// ---------------------------------------------------------------------------\n// Path-like argument keys\n// ---------------------------------------------------------------------------\n\nconst _PATH_ARG_KEYS = new Set([\n 'path',\n 'file_path',\n 'filePath',\n 'directory',\n 'dir',\n 'folder',\n 'target',\n 'destination',\n 'source',\n 'src',\n 'dst',\n // Common path-like arg names from AI framework tool calls.\n // IMPORTANT: Only include keys that are unambiguously path-related.\n // Generic keys like 'name', 'input', 'output', 'from', 'to' are excluded\n // because they frequently hold non-path values (e.g., { from: \"English\" }),\n // and resolvePath() would produce false positives. The heuristic loop below\n // catches path-like VALUES in any key (containing '..', '~', or '/').\n 'filename',\n 'file',\n 'filepath',\n 'read_path',\n 'write_path',\n])\n\n// ---------------------------------------------------------------------------\n// Resource extraction\n// ---------------------------------------------------------------------------\n\n/** Extract file paths from an envelope for sandbox evaluation. */\nexport function extractPaths(envelope: ToolEnvelope): string[] {\n const paths: string[] = []\n const seen = new Set<string>()\n\n function add(p: string): void {\n if (!p) return\n const resolved = resolvePath(p)\n if (!seen.has(resolved)) {\n seen.add(resolved)\n paths.push(resolved)\n }\n }\n\n if (envelope.filePath) add(envelope.filePath)\n\n const args = envelope.args as Record<string, unknown>\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && _PATH_ARG_KEYS.has(key)) add(value)\n }\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && value.startsWith('/') && !_PATH_ARG_KEYS.has(key)) add(value)\n }\n\n // Catch path-like values in unrecognized keys (relative paths, ~, etc.)\n // NOTE: Absolute paths (starting with /) in unknown keys are already caught\n // above at line 159. This loop covers relative path patterns only.\n // The slash check requires './' or '../' prefix to avoid false positives on\n // non-path values like 'application/json', '1/2', etc.\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && !_PATH_ARG_KEYS.has(key)) {\n // Exclude URLs — they are handled separately by extractUrls/domain checks\n const isUrl = value.includes('://')\n if (\n (!isUrl && value.includes('../')) || // embedded traversal: foo/../etc/passwd\n value === '..' || // bare parent reference\n value.startsWith('../') || // parent traversal prefix: ../../etc/passwd\n value.startsWith('~') ||\n (value.startsWith('./') && !isUrl) // relative child: ./subdir/file\n ) {\n add(value)\n }\n }\n }\n\n const cmd = envelope.bashCommand ?? (args.command as string | undefined) ?? ''\n if (cmd) {\n for (const token of tokenizeCommand(cmd)) {\n if (token.startsWith('/')) add(token)\n }\n }\n return paths\n}\n\n/** Extract the first command token from an envelope (shell-aware). */\nexport function extractCommand(envelope: ToolEnvelope): string | null {\n const cmd = envelope.bashCommand ?? (envelope.args as Record<string, unknown>).command\n if (!cmd || typeof cmd !== 'string') return null\n const stripped = cmd.trim()\n if (!stripped) return null\n\n // Check for shell command separators/metacharacters BEFORE extracting.\n // If any are present, the shell would execute multiple commands — return\n // sentinel value that never matches any allowlist.\n if (_SHELL_SEPARATOR_RE.test(stripped)) return '\\x00'\n\n const rawFirst = stripped.split(/\\s/)[0] ?? ''\n if (_REDIRECT_PREFIX_RE.test(rawFirst)) return '\\x00'\n\n const tokens = tokenizeCommand(stripped)\n return tokens.length > 0 ? (tokens[0] ?? null) : null\n}\n\n/** Extract URL strings from envelope args (shell-aware). */\nexport function extractUrls(envelope: ToolEnvelope): string[] {\n const urls: string[] = []\n const seen = new Set<string>()\n\n function addUrl(u: string): void {\n if (!seen.has(u)) {\n seen.add(u)\n urls.push(u)\n }\n }\n\n for (const value of Object.values(envelope.args)) {\n if (typeof value !== 'string' || !value.includes('://')) continue\n if (extractHostname(value) !== null) {\n addUrl(value)\n } else {\n for (const token of tokenizeCommand(value)) {\n if (token.includes('://') && extractHostname(token) !== null) addUrl(token)\n }\n }\n }\n return urls\n}\n\n/** Extract hostname from a URL string. */\nexport function extractHostname(url: string): string | null {\n try {\n return new URL(url).hostname || null\n } catch {\n return null\n }\n}\n\n/** Check if hostname matches any domain pattern (supports wildcards). */\nexport function domainMatches(hostname: string, patterns: string[]): boolean {\n return patterns.some((p) => fnmatch(hostname, p))\n}\n","/** compileSandbox — compile a sandbox contract YAML dict into a callable with metadata. */\n\nimport { Verdict } from '../contracts.js'\nimport type { ToolEnvelope } from '../envelope.js'\nimport { expandMessage } from './compiler-utils.js'\nimport {\n extractPaths,\n extractCommand,\n extractUrls,\n extractHostname,\n domainMatches,\n} from './sandbox-compiler.js'\n\nimport { resolvePath } from './resolve-path.js'\n\n/** Check if a path is within an allowed prefix. */\nfunction _pathWithin(filePath: string, prefix: string): boolean {\n return filePath === prefix || filePath.startsWith(prefix.replace(/\\/+$/, '') + '/')\n}\n\n/**\n * Compile a sandbox contract into a callable with _edictum_* metadata.\n *\n * The returned object has a `check` function and stamped metadata properties\n * for pipeline routing.\n */\nexport function compileSandbox(\n contract: Record<string, unknown>,\n mode: string,\n): Record<string, unknown> {\n const contractId = contract.id as string\n\n // Normalize tool/tools to a list\n const toolPatterns: string[] =\n 'tools' in contract ? (contract.tools as string[]) : [contract.tool as string]\n\n const within = ((contract.within ?? []) as string[]).map(resolvePath)\n const notWithin = ((contract.not_within ?? []) as string[]).map(resolvePath)\n const allows = (contract.allows ?? {}) as Record<string, unknown>\n const notAllows = (contract.not_allows ?? {}) as Record<string, unknown>\n const allowedCommands = (allows.commands ?? []) as string[]\n const allowedDomains = (allows.domains ?? []) as string[]\n const blockedDomains = (notAllows.domains ?? []) as string[]\n const outside = (contract.outside as string) ?? 'deny'\n const messageTemplate = (contract.message as string) ?? 'Tool call outside sandbox boundary.'\n const timeout = (contract.timeout as number) ?? 300\n const timeoutEffect = (contract.timeout_effect as string) ?? 'deny'\n\n const check = (envelope: ToolEnvelope): Verdict => {\n // Path checks — FAIL-CLOSED when sandbox declares path boundaries\n if (within.length > 0 || notWithin.length > 0) {\n const paths = extractPaths(envelope)\n\n // FAIL-CLOSED: If the sandbox declares path boundaries (within/not_within)\n // but we couldn't extract any paths from the tool call, we DENY.\n // Rationale: we can't verify what we can't see. An attacker who crafts\n // args that bypass extractPaths() should not get a free pass.\n if (paths.length === 0 && within.length > 0) {\n return Verdict.fail(\n expandMessage(messageTemplate, envelope) +\n ' (no extractable paths — sandbox cannot verify boundary compliance)',\n )\n }\n\n if (paths.length > 0) {\n for (const p of paths) {\n for (const excluded of notWithin) {\n if (_pathWithin(p, excluded)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope))\n }\n }\n }\n if (within.length > 0) {\n for (const p of paths) {\n if (!within.some((allowed) => _pathWithin(p, allowed))) {\n return Verdict.fail(expandMessage(messageTemplate, envelope))\n }\n }\n }\n }\n }\n\n // Command checks\n if (allowedCommands.length > 0) {\n const firstToken = extractCommand(envelope)\n if (firstToken !== null && !allowedCommands.includes(firstToken)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope))\n }\n }\n\n // Domain checks\n const urls = extractUrls(envelope)\n if (urls.length > 0) {\n for (const url of urls) {\n const hostname = extractHostname(url)\n if (hostname) {\n if (blockedDomains.length > 0 && domainMatches(hostname, blockedDomains)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope))\n }\n if (allowedDomains.length > 0 && !domainMatches(hostname, allowedDomains)) {\n return Verdict.fail(expandMessage(messageTemplate, envelope))\n }\n } else if (allowedDomains.length > 0) {\n // Fail-closed: URLs without extractable hostname (file://, data:, etc.)\n // cannot be verified against domain allowlist → deny\n return Verdict.fail(expandMessage(messageTemplate, envelope))\n }\n }\n }\n\n return Verdict.pass_()\n }\n\n const result: Record<string, unknown> = {\n check,\n name: contractId,\n tool: toolPatterns.length === 1 ? toolPatterns[0] : undefined,\n _edictum_type: 'sandbox',\n _edictum_tools: toolPatterns,\n _edictum_mode: mode,\n _edictum_id: contractId,\n _edictum_source: 'yaml_sandbox',\n _edictum_effect: outside,\n _edictum_timeout: timeout,\n _edictum_timeout_effect: timeoutEffect,\n }\n\n // Use _observe (TS) not _shadow (Python). Strict === true to prevent\n // truthy coercion of non-boolean values (e.g., strings, numbers).\n if (contract._observe === true || contract._shadow === true) {\n result._edictum_observe = true\n }\n\n return result\n}\n","/** Compiler — convert parsed YAML contracts into contract objects and OperationLimits. */\n\nimport type { OperationLimits } from '../limits.js'\nimport { DEFAULT_LIMITS } from '../limits.js'\nimport type { CustomOperator, CustomSelector } from './evaluator.js'\nimport { EdictumConfigError } from '../errors.js'\nimport { validateOperators } from './compiler-utils.js'\nimport { compilePre, compilePost, compileSession, mergeSessionLimits } from './compile-contracts.js'\nimport { compileSandbox } from './sandbox-compile-fn.js'\n\n// ---------------------------------------------------------------------------\n// CompiledBundle\n// ---------------------------------------------------------------------------\n\n/** Result of compiling a YAML contract bundle. */\nexport interface CompiledBundle {\n readonly preconditions: readonly unknown[]\n readonly postconditions: readonly unknown[]\n readonly sessionContracts: readonly unknown[]\n readonly sandboxContracts: readonly unknown[]\n readonly limits: OperationLimits\n readonly defaultMode: string\n readonly tools: Readonly<Record<string, Record<string, unknown>>>\n}\n\n// ---------------------------------------------------------------------------\n// Compile options\n// ---------------------------------------------------------------------------\n\nexport interface CompileOptions {\n readonly customOperators?: Readonly<Record<string, CustomOperator>> | null\n readonly customSelectors?: Readonly<Record<string, CustomSelector>> | null\n}\n\n// ---------------------------------------------------------------------------\n// Main entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a validated YAML bundle into contract objects.\n *\n * @param bundle - A validated bundle dict (output of loadBundle).\n * @param options - Optional custom operators and selectors.\n * @returns CompiledBundle with preconditions, postconditions, sessionContracts,\n * and merged OperationLimits.\n */\nexport function compileContracts(\n bundle: Record<string, unknown>,\n options: CompileOptions = {},\n): CompiledBundle {\n const customOps = options?.customOperators ?? null\n const customSels = options?.customSelectors ?? null\n\n validateOperators(bundle, customOps)\n\n if (bundle.defaults == null || typeof bundle.defaults !== 'object') {\n throw new EdictumConfigError(\"Bundle missing required 'defaults' section with 'mode' field\")\n }\n const defaults = bundle.defaults as Record<string, unknown>\n const defaultMode = defaults.mode as string\n const preconditions: unknown[] = []\n const postconditions: unknown[] = []\n const sessionContracts: unknown[] = []\n const sandboxContracts: unknown[] = []\n let limits: OperationLimits = { ...DEFAULT_LIMITS }\n\n const contracts = (bundle.contracts ?? []) as Record<string, unknown>[]\n for (const contract of contracts) {\n // Skip disabled contracts\n if (contract.enabled === false) continue\n\n const contractType = contract.type as string\n const contractMode = (contract.mode as string) ?? defaultMode\n\n if (contractType === 'pre') {\n preconditions.push(compilePre(contract, contractMode, customOps, customSels))\n } else if (contractType === 'post') {\n postconditions.push(compilePost(contract, contractMode, customOps, customSels))\n } else if (contractType === 'session') {\n // Use _observe (TS) not _shadow (Python)\n const isObserve = (contract._observe as boolean) ?? (contract._shadow as boolean) ?? false\n if (!isObserve) {\n limits = mergeSessionLimits(contract, limits)\n }\n sessionContracts.push(compileSession(contract, contractMode, limits))\n } else if (contractType === 'sandbox') {\n sandboxContracts.push(compileSandbox(contract, contractMode))\n } else {\n throw new EdictumConfigError(\n `Unknown contract type \"${contractType}\" in contract \"${contract.id ?? 'unknown'}\". ` +\n `Expected \"pre\", \"post\", \"session\", or \"sandbox\".`,\n )\n }\n }\n\n const tools = (bundle.tools ?? {}) as Record<string, Record<string, unknown>>\n\n return {\n preconditions,\n postconditions,\n sessionContracts,\n sandboxContracts,\n limits,\n defaultMode,\n tools,\n }\n}\n","/** YAML Bundle Loader — parse, validate, compute bundle hash. */\n\nimport { createHash } from 'node:crypto'\nimport { readFileSync, realpathSync, statSync } from 'node:fs'\n\nimport yaml from 'js-yaml'\n\nimport { EdictumConfigError } from '../errors.js'\nimport {\n validateSchema,\n validateUniqueIds,\n validateRegexes,\n validatePreSelectors,\n validateSandboxContracts,\n} from './loader-validators.js'\nimport { validateContractFields } from './loader-field-validators.js'\nimport { validateExpressionShapes } from './loader-expression-validators.js'\n\n// Re-export validators for direct access\nexport {\n validateSchema,\n validateUniqueIds,\n validateRegexes,\n validatePreSelectors,\n validateSandboxContracts,\n} from './loader-validators.js'\nexport { validateContractFields } from './loader-field-validators.js'\nexport { validateExpressionShapes } from './loader-expression-validators.js'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum bundle file size in bytes (1 MB). */\nexport const MAX_BUNDLE_SIZE = 1_048_576\n\n// ---------------------------------------------------------------------------\n// BundleHash\n// ---------------------------------------------------------------------------\n\n/** SHA256 hash of raw YAML bytes, used as policy_version. */\nexport interface BundleHash {\n readonly hex: string\n}\n\n/** Compute SHA256 hash of raw YAML bytes. */\nexport function computeHash(rawBytes: Uint8Array): BundleHash {\n return { hex: createHash('sha256').update(rawBytes).digest('hex') }\n}\n\n// ---------------------------------------------------------------------------\n// YAML parsing\n// ---------------------------------------------------------------------------\n\n/** Parse YAML content string, returning the parsed object. */\nfunction parseYaml(content: string): Record<string, unknown> {\n let data: unknown\n try {\n data = yaml.load(content, { schema: yaml.CORE_SCHEMA })\n } catch (e) {\n throw new EdictumConfigError(`YAML parse error: ${String(e)}`)\n }\n if (data == null || typeof data !== 'object' || Array.isArray(data)) {\n throw new EdictumConfigError('YAML document must be a mapping')\n }\n return data as Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Validation pipeline\n// ---------------------------------------------------------------------------\n\n/** Run all bundle validations in sequence. */\nfunction validateBundle(data: Record<string, unknown>): void {\n validateSchema(data)\n validateContractFields(data)\n validateUniqueIds(data)\n validateExpressionShapes(data)\n validateRegexes(data)\n validatePreSelectors(data)\n validateSandboxContracts(data)\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Load and validate a YAML contract bundle from a file path.\n *\n * @returns Tuple of [parsed bundle dict, bundle hash].\n * @throws EdictumConfigError on validation failure.\n * @throws Error if the file does not exist.\n */\nexport function loadBundle(source: string): [Record<string, unknown>, BundleHash] {\n // Resolve symlinks before reading to prevent path traversal attacks.\n const resolved = realpathSync(source)\n const fileSize = statSync(resolved).size\n if (fileSize > MAX_BUNDLE_SIZE) {\n throw new EdictumConfigError(\n `Bundle file too large (${fileSize} bytes, max ${MAX_BUNDLE_SIZE})`,\n )\n }\n\n const rawBytes = readFileSync(resolved)\n const bundleHash = computeHash(rawBytes)\n const data = parseYaml(rawBytes.toString('utf-8'))\n\n validateBundle(data)\n return [data, bundleHash]\n}\n\n/**\n * Load and validate a YAML contract bundle from a string or bytes.\n *\n * Like {@link loadBundle} but accepts YAML content directly instead of\n * a file path. Useful when YAML is generated programmatically or fetched\n * from an API.\n *\n * @returns Tuple of [parsed bundle dict, bundle hash].\n * @throws EdictumConfigError on validation failure.\n */\nexport function loadBundleString(\n content: string | Uint8Array,\n): [Record<string, unknown>, BundleHash] {\n const rawBytes = typeof content === 'string' ? new TextEncoder().encode(content) : content\n\n if (rawBytes.length > MAX_BUNDLE_SIZE) {\n throw new EdictumConfigError(\n `Bundle content too large (${rawBytes.length} bytes, max ${MAX_BUNDLE_SIZE})`,\n )\n }\n\n const bundleHash = computeHash(rawBytes)\n const text = typeof content === 'string' ? content : new TextDecoder().decode(rawBytes)\n const data = parseYaml(text)\n\n validateBundle(data)\n return [data, bundleHash]\n}\n","/** Loader validation helpers — schema, uniqueness, regex, selector, and sandbox checks. */\n\nimport { EdictumConfigError } from '../errors.js'\n\n// ---------------------------------------------------------------------------\n// Schema validation (structural — no JSON Schema dependency)\n// ---------------------------------------------------------------------------\n\n/**\n * Basic structural validation of a parsed YAML bundle.\n *\n * Checks apiVersion, kind, metadata, and contracts array.\n * Full JSON Schema validation requires the edictum-schemas package (future).\n */\nexport function validateSchema(data: Record<string, unknown>): void {\n if (data.apiVersion !== 'edictum/v1') {\n throw new EdictumConfigError(\n `Schema validation failed: apiVersion must be 'edictum/v1', got '${String(data.apiVersion)}'`,\n )\n }\n if (data.kind !== 'ContractBundle') {\n throw new EdictumConfigError(\n `Schema validation failed: kind must be 'ContractBundle', got '${String(data.kind)}'`,\n )\n }\n if (data.metadata != null && typeof data.metadata !== 'object') {\n throw new EdictumConfigError('Schema validation failed: metadata must be an object')\n }\n if (!Array.isArray(data.contracts)) {\n throw new EdictumConfigError('Schema validation failed: contracts must be an array')\n }\n}\n\n// ---------------------------------------------------------------------------\n// Unique IDs\n// ---------------------------------------------------------------------------\n\n// Reject control characters in contract IDs — null bytes, newlines, carriage\n// returns, and other C0/C1 control chars could corrupt storage keys or logs.\nconst CONTROL_CHAR_RE = /[\\x00-\\x1f\\x7f-\\x9f\\u2028\\u2029]/\n\n// JSON Schema: \"pattern\": \"^[a-z0-9][a-z0-9_-]*$\"\nconst CONTRACT_ID_RE = /^[a-z0-9][a-z0-9_-]*$/\n\n/** Validate a single contract ID for dangerous characters and format. */\nfunction validateContractId(contractId: string): void {\n if (contractId.length > 10_000) {\n throw new EdictumConfigError('Contract id exceeds maximum length')\n }\n // Control chars checked first — more specific error than pattern mismatch.\n if (CONTROL_CHAR_RE.test(contractId)) {\n throw new EdictumConfigError(\n `Contract id contains control characters: '${contractId.replace(CONTROL_CHAR_RE, '\\\\x??')}'`,\n )\n }\n if (!CONTRACT_ID_RE.test(contractId)) {\n throw new EdictumConfigError(\n `Contract id '${contractId}' must match pattern ^[a-z0-9][a-z0-9_-]*$`,\n )\n }\n}\n\n/** Ensure all contract IDs are unique within the bundle and free of control characters. */\nexport function validateUniqueIds(data: Record<string, unknown>): void {\n const ids = new Set<string>()\n const contracts = (data.contracts ?? []) as Record<string, unknown>[]\n for (const contract of contracts) {\n const contractId = contract.id as string | undefined\n if (contractId != null) {\n validateContractId(contractId)\n if (ids.has(contractId)) {\n throw new EdictumConfigError(`Duplicate contract id: '${contractId}'`)\n }\n ids.add(contractId)\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Regex validation\n// ---------------------------------------------------------------------------\n\n/** Compile all regex patterns at load time to catch invalid patterns early. */\nexport function validateRegexes(data: Record<string, unknown>): void {\n const contracts = (data.contracts ?? []) as Record<string, unknown>[]\n for (const contract of contracts) {\n const when = contract.when\n if (when != null) {\n validateExpressionRegexes(when as Record<string, unknown>)\n }\n }\n}\n\n/** Recursively validate regex patterns in expressions. */\nfunction validateExpressionRegexes(expr: unknown): void {\n if (expr == null || typeof expr !== 'object') return\n const e = expr as Record<string, unknown>\n\n if ('all' in e) {\n for (const sub of e.all as unknown[]) validateExpressionRegexes(sub)\n return\n }\n if ('any' in e) {\n for (const sub of e.any as unknown[]) validateExpressionRegexes(sub)\n return\n }\n if ('not' in e) {\n validateExpressionRegexes(e.not)\n return\n }\n\n // Leaf node: selector -> operator\n for (const operator of Object.values(e)) {\n if (operator == null || typeof operator !== 'object') continue\n const op = operator as Record<string, unknown>\n if ('matches' in op) tryCompileRegex(op.matches as string)\n if ('matches_any' in op) {\n for (const pattern of op.matches_any as string[]) tryCompileRegex(pattern)\n }\n }\n}\n\n/** Attempt to compile a regex, raising EdictumConfigError on failure. */\nfunction tryCompileRegex(pattern: string): void {\n try {\n new RegExp(pattern)\n } catch (e) {\n throw new EdictumConfigError(`Invalid regex pattern '${pattern}': ${String(e)}`)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pre-selector validation\n// ---------------------------------------------------------------------------\n\n/** Reject output.text selectors in type: pre contracts (spec violation). */\nexport function validatePreSelectors(data: Record<string, unknown>): void {\n const contracts = (data.contracts ?? []) as Record<string, unknown>[]\n for (const contract of contracts) {\n if (contract.type !== 'pre') continue\n const when = contract.when\n if (when != null && expressionHasSelector(when as Record<string, unknown>, 'output.text')) {\n throw new EdictumConfigError(\n `Contract '${(contract.id as string) ?? '?'}': output.text selector is not available in type: pre contracts`,\n )\n }\n }\n}\n\n/** Check if an expression tree contains a specific selector. */\nfunction expressionHasSelector(expr: unknown, target: string): boolean {\n if (expr == null || typeof expr !== 'object') return false\n const e = expr as Record<string, unknown>\n if ('all' in e) return (e.all as unknown[]).some((sub) => expressionHasSelector(sub, target))\n if ('any' in e) return (e.any as unknown[]).some((sub) => expressionHasSelector(sub, target))\n if ('not' in e) return expressionHasSelector(e.not, target)\n return target in e\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox contract validation\n// ---------------------------------------------------------------------------\n\n/** Validate sandbox contract field dependencies. */\nexport function validateSandboxContracts(data: Record<string, unknown>): void {\n const contracts = (data.contracts ?? []) as Record<string, unknown>[]\n for (const contract of contracts) {\n if (contract.type !== 'sandbox') continue\n const cid = (contract.id as string) ?? '?'\n\n if ('not_within' in contract && !('within' in contract)) {\n throw new EdictumConfigError(`Contract '${cid}': not_within requires within to also be set`)\n }\n if ('not_allows' in contract && !('allows' in contract)) {\n throw new EdictumConfigError(`Contract '${cid}': not_allows requires allows to also be set`)\n }\n if ('not_allows' in contract) {\n const notAllows = (contract.not_allows ?? {}) as Record<string, unknown>\n if ('domains' in notAllows) {\n const allows = (contract.allows ?? {}) as Record<string, unknown>\n if (!('domains' in allows)) {\n throw new EdictumConfigError(\n `Contract '${cid}': not_allows.domains requires allows.domains to also be set`,\n )\n }\n }\n }\n }\n}\n","/**\n * Contract-level structural validation — enforces required fields, type\n * constraints, effect enums, and expression shapes that the JSON Schema\n * spec mandates. Hand-rolled to match Go's validation approach and keep\n * cross-SDK implementation strategy aligned.\n */\n\nimport { EdictumConfigError } from '../errors.js'\n\n// ---------------------------------------------------------------------------\n// Allowed values (mirrors edictum-v1.schema.json enums)\n// ---------------------------------------------------------------------------\n\nconst VALID_CONTRACT_TYPES = new Set(['pre', 'post', 'session', 'sandbox'])\nconst PRE_EFFECTS = new Set(['deny', 'approve'])\nconst POST_EFFECTS = new Set(['warn', 'redact', 'deny'])\nconst VALID_MODES = new Set(['enforce', 'observe'])\nconst VALID_SIDE_EFFECTS = new Set(['pure', 'read', 'write', 'irreversible'])\nconst KNOWN_TOP_LEVEL = new Set([\n 'apiVersion',\n 'kind',\n 'metadata',\n 'defaults',\n 'contracts',\n 'tools',\n 'observability',\n 'observe_alongside',\n])\nconst METADATA_NAME_RE = /^[a-z0-9][a-z0-9._-]*$/\nconst MAX_MESSAGE_LENGTH = 500\n/** Throw EdictumConfigError with a \"Schema validation failed:\" prefix. */\nfunction fail(msg: string): never {\n throw new EdictumConfigError(`Schema validation failed: ${msg}`)\n}\n\n// ---------------------------------------------------------------------------\n// Top-level + per-contract structural validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate contract-level structural requirements that Python enforces via\n * JSON Schema. Must run **after** `validateSchema()` (which guarantees\n * apiVersion, kind, and contracts-is-array) and **before** `validateUniqueIds()`.\n */\nexport function validateContractFields(data: Record<string, unknown>): void {\n // --- Unknown top-level fields (additionalProperties: false) ---\n for (const key of Object.keys(data)) {\n if (!KNOWN_TOP_LEVEL.has(key)) fail(`unknown top-level field '${key}'`)\n }\n\n // --- metadata required with name ---\n if (data.metadata == null || typeof data.metadata !== 'object' || Array.isArray(data.metadata)) {\n fail(\"'metadata' is required and must be an object\")\n }\n const meta = data.metadata as Record<string, unknown>\n if (meta.name == null || typeof meta.name !== 'string') fail('metadata.name is required')\n const metaName = meta.name as string\n if (metaName.length > 10_000) fail('metadata.name exceeds maximum length')\n if (!METADATA_NAME_RE.test(metaName)) {\n fail(\n `metadata.name must be a lowercase slug (^[a-z0-9][a-z0-9._-]*$), got '${metaName.slice(0, 100)}'`,\n )\n }\n\n // --- defaults required with valid mode ---\n if (data.defaults == null || typeof data.defaults !== 'object' || Array.isArray(data.defaults)) {\n fail(\"'defaults' is required and must be an object\")\n }\n const mode = (data.defaults as Record<string, unknown>).mode\n if (!VALID_MODES.has(mode as string)) {\n fail(`defaults.mode must be 'enforce' or 'observe', got '${String(mode)}'`)\n }\n\n // --- contracts minItems: 1 ---\n const contracts = data.contracts as Record<string, unknown>[]\n if (contracts.length === 0) fail('contracts must contain at least 1 item')\n\n // --- tools side_effect enum ---\n if (data.tools != null) {\n if (typeof data.tools !== 'object' || Array.isArray(data.tools)) {\n fail(\"'tools' must be a mapping of tool names to descriptors, not an array\")\n }\n for (const [tn, td] of Object.entries(data.tools as Record<string, unknown>)) {\n if (td == null || typeof td !== 'object' || Array.isArray(td)) {\n fail(`tools.${tn} must be an object with a 'side_effect' field`)\n }\n const se = (td as Record<string, unknown>).side_effect\n if (!VALID_SIDE_EFFECTS.has(se as string)) {\n fail(\n `tools.${tn}.side_effect must be 'pure', 'read', 'write', or 'irreversible', got '${String(se)}'`,\n )\n }\n }\n }\n\n // --- Per-contract validation ---\n for (const c of contracts) {\n if (c == null || typeof c !== 'object' || Array.isArray(c)) {\n fail('every contract must be an object (got null or non-object array element)')\n }\n if (c.id == null || typeof c.id !== 'string' || c.id.length === 0) {\n fail(\"every contract requires a non-empty 'id' string\")\n }\n const cid = c.id as string\n if (!VALID_CONTRACT_TYPES.has(c.type as string)) {\n fail(`contract '${cid}': invalid type '${String(c.type)}'`)\n }\n const t = c.type as string\n\n if (t === 'pre' || t === 'post') validatePrePost(c, t, cid)\n else if (t === 'session') validateSession(c, cid)\n else if (t === 'sandbox') validateSandboxStructure(c, cid)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pre/Post contract validation\n// ---------------------------------------------------------------------------\n\nfunction validatePrePost(c: Record<string, unknown>, t: string, cid: string): void {\n if (c.tool == null || typeof c.tool !== 'string') {\n fail(`${t} contract '${cid}' requires 'tool' to be a string`)\n }\n if (c.when == null || typeof c.when !== 'object' || Array.isArray(c.when)) {\n fail(\n `${t} contract '${cid}' requires 'when' to be a mapping (got ${Array.isArray(c.when) ? 'array' : typeof c.when})`,\n )\n }\n if (c.then == null || typeof c.then !== 'object' || Array.isArray(c.then)) {\n fail(`${t} contract '${cid}' requires 'then' to be a mapping`)\n }\n\n const then = c.then as Record<string, unknown>\n if (then.effect == null) fail(`${t} contract '${cid}' requires 'then.effect'`)\n if (then.message == null) fail(`${t} contract '${cid}' requires 'then.message'`)\n validateMessageLength(then.message, `${t} contract '${cid}'`)\n\n const effect = then.effect as string\n if (t === 'pre' && !PRE_EFFECTS.has(effect)) {\n fail(`pre contract '${cid}': effect must be 'deny' or 'approve', got '${effect}'`)\n }\n if (t === 'post' && !POST_EFFECTS.has(effect)) {\n fail(`post contract '${cid}': effect must be 'warn', 'redact', or 'deny', got '${effect}'`)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Session contract validation\n// ---------------------------------------------------------------------------\n\nfunction validateSession(c: Record<string, unknown>, cid: string): void {\n if (c.limits == null || typeof c.limits !== 'object' || Array.isArray(c.limits)) {\n fail(`session contract '${cid}' requires 'limits' to be a mapping`)\n }\n const lim = c.limits as Record<string, unknown>\n if (!('max_tool_calls' in lim) && !('max_attempts' in lim) && !('max_calls_per_tool' in lim)) {\n fail(\n `session contract '${cid}': limits must have max_tool_calls, max_attempts, or max_calls_per_tool`,\n )\n }\n\n if (c.then == null || typeof c.then !== 'object' || Array.isArray(c.then)) {\n fail(`session contract '${cid}' requires 'then' to be a mapping`)\n }\n const then = c.then as Record<string, unknown>\n if (then.effect !== 'deny') {\n fail(`session contract '${cid}': effect must be 'deny', got '${String(then.effect)}'`)\n }\n if (then.message == null) fail(`session contract '${cid}' requires 'then.message'`)\n validateMessageLength(then.message, `session contract '${cid}'`)\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox contract structure (complements validateSandboxContracts)\n// ---------------------------------------------------------------------------\n\nfunction validateSandboxStructure(c: Record<string, unknown>, cid: string): void {\n if (c.tool == null && c.tools == null) {\n fail(`sandbox contract '${cid}' requires either 'tool' or 'tools'`)\n }\n if (c.tool != null && typeof c.tool !== 'string') {\n fail(`sandbox contract '${cid}': 'tool' must be a string`)\n }\n if (c.tools != null && (!Array.isArray(c.tools) || (c.tools as unknown[]).length === 0)) {\n fail(`sandbox contract '${cid}': 'tools' must be a non-empty array`)\n }\n if (c.within == null && c.allows == null) {\n fail(`sandbox contract '${cid}' requires either 'within' or 'allows'`)\n }\n if (c.within != null && (!Array.isArray(c.within) || (c.within as unknown[]).length === 0)) {\n fail(`sandbox contract '${cid}': 'within' must be a non-empty array`)\n }\n if (c.message == null) fail(`sandbox contract '${cid}' requires 'message'`)\n validateMessageLength(c.message, `sandbox contract '${cid}'`)\n}\n\n// ---------------------------------------------------------------------------\n// Message length constraint (maxLength: 500)\n// ---------------------------------------------------------------------------\n\nfunction validateMessageLength(msg: unknown, context: string): void {\n if (typeof msg !== 'string') {\n fail(`${context}: message must be a string`)\n }\n if (msg.length > MAX_MESSAGE_LENGTH) {\n fail(`${context}: message exceeds ${MAX_MESSAGE_LENGTH} characters`)\n }\n}\n","/** Expression shape validation — empty all/any guards and operator type constraints. */\n\nimport { EdictumConfigError } from '../errors.js'\n\nconst NUMERIC_OPS = new Set(['gt', 'gte', 'lt', 'lte'])\nconst STRING_OPS = new Set(['contains', 'starts_with', 'ends_with'])\nconst ARRAY_MIN1_OPS = new Set(['in', 'not_in', 'contains_any', 'matches_any'])\n\nfunction fail(msg: string): never {\n throw new EdictumConfigError(`Schema validation failed: ${msg}`)\n}\n\n/** Validate expression tree shapes and operator value types. */\nexport function validateExpressionShapes(data: Record<string, unknown>): void {\n for (const c of (data.contracts ?? []) as unknown[]) {\n if (c == null || typeof c !== 'object') continue\n const contract = c as Record<string, unknown>\n if (contract.when != null) checkExprShape(contract.when, (contract.id as string) ?? '?')\n }\n}\n\nconst MAX_EXPR_DEPTH = 50\n\nfunction checkExprShape(expr: unknown, cid: string, depth = 0): void {\n if (depth > MAX_EXPR_DEPTH)\n fail(`contract '${cid}': expression nesting exceeds maximum depth (${MAX_EXPR_DEPTH})`)\n if (expr == null || typeof expr !== 'object') return\n const e = expr as Record<string, unknown>\n\n if ('all' in e) {\n const a = e.all\n if (!Array.isArray(a) || a.length === 0)\n fail(`contract '${cid}': 'all' requires a non-empty array`)\n for (const s of a) checkExprShape(s, cid, depth + 1)\n return\n }\n if ('any' in e) {\n const a = e.any\n if (!Array.isArray(a) || a.length === 0)\n fail(`contract '${cid}': 'any' requires a non-empty array`)\n for (const s of a) checkExprShape(s, cid, depth + 1)\n return\n }\n if ('not' in e) {\n if (e.not == null || typeof e.not !== 'object' || Array.isArray(e.not)) {\n fail(\n `contract '${cid}': 'not' requires an expression mapping (got ${e.not === null ? 'null' : Array.isArray(e.not) ? 'array' : typeof e.not})`,\n )\n }\n checkExprShape(e.not, cid, depth + 1)\n return\n }\n\n // Leaf: validate operator value types\n for (const v of Object.values(e)) {\n if (v == null || typeof v !== 'object') continue\n if (Array.isArray(v)) {\n fail(`contract '${cid}': selector value must be an operator mapping, not an array`)\n }\n const op = v as Record<string, unknown>\n for (const [name, val] of Object.entries(op)) {\n if (NUMERIC_OPS.has(name) && typeof val !== 'number') {\n fail(`contract '${cid}': operator '${name}' requires a number, got ${typeof val}`)\n }\n if (STRING_OPS.has(name) && typeof val !== 'string') {\n fail(`contract '${cid}': operator '${name}' requires a string, got ${typeof val}`)\n }\n if (ARRAY_MIN1_OPS.has(name) && (!Array.isArray(val) || val.length === 0)) {\n fail(`contract '${cid}': operator '${name}' requires a non-empty array`)\n }\n }\n }\n}\n","/** Edictum — Runtime contract enforcement for AI agent tool calls. */\n\nexport const VERSION = '0.1.0'\n\n// Errors\nexport { EdictumConfigError, EdictumDenied, EdictumToolError } from './errors.js'\n\n// Envelope & Classification\nexport {\n BashClassifier,\n createEnvelope,\n createPrincipal,\n deepFreeze,\n SideEffect,\n ToolRegistry,\n _validateToolName,\n} from './envelope.js'\nexport type { CreateEnvelopeOptions, Principal, ToolEnvelope } from './envelope.js'\n\n// Contracts\nexport { Verdict } from './contracts.js'\nexport type { Precondition, Postcondition, SessionContract } from './contracts.js'\n\n// Hooks\nexport { HookDecision, HookResult } from './hooks.js'\n\n// Limits\nexport { DEFAULT_LIMITS } from './limits.js'\nexport type { OperationLimits } from './limits.js'\n\n// Types (internal, but exported for adapter authors)\nexport type { HookRegistration, ToolConfig } from './types.js'\n\n// Storage\nexport { MemoryBackend } from './storage.js'\nexport type { StorageBackend } from './storage.js'\n\n// Session\nexport { Session } from './session.js'\n\n// Approval\nexport { ApprovalStatus, LocalApprovalBackend } from './approval.js'\nexport type { ApprovalBackend, ApprovalDecision, ApprovalRequest } from './approval.js'\n\n// Audit\nexport {\n AuditAction,\n CollectingAuditSink,\n CompositeSink,\n createAuditEvent,\n FileAuditSink,\n MarkEvictedError,\n StdoutAuditSink,\n} from './audit.js'\nexport type { AuditEvent, AuditSink } from './audit.js'\n\n// Redaction\nexport { RedactionPolicy } from './redaction.js'\n\n// Evaluation\nexport { createContractResult, createEvaluationResult } from './evaluation.js'\nexport type { ContractResult, EvaluationResult } from './evaluation.js'\n\n// Findings\nexport { buildFindings, classifyFinding, createFinding, createPostCallResult } from './findings.js'\nexport type { Finding, PostCallResult, PostDecisionLike } from './findings.js'\n\n// Internal contract types (for adapter and YAML engine authors)\nexport type {\n GuardLike,\n InternalContract,\n InternalPrecondition,\n InternalPostcondition,\n InternalSessionContract,\n InternalSandboxContract,\n} from './internal-contracts.js'\n\n// Compiled state\nexport { createCompiledState } from './compiled-state.js'\nexport type { CompiledState } from './compiled-state.js'\n\n// Pipeline\nexport { GovernancePipeline, createPreDecision, createPostDecision } from './pipeline.js'\nexport type { PreDecision, PostDecision } from './pipeline.js'\n\n// Guard\nexport { Edictum } from './guard.js'\nexport type { EdictumOptions } from './guard.js'\n\n// Runner (framework-agnostic tool execution)\nexport { defaultSuccessCheck, run } from './runner.js'\nexport type { RunOptions } from './runner.js'\n\n// Dry-run evaluation\nexport type { BatchCall, EvaluateOptions } from './dry-run.js'\n\n// Fnmatch\nexport { fnmatch } from './fnmatch.js'\n\n// YAML Factory\nexport { fromYaml, fromYamlString, reload } from './factory.js'\nexport type { YamlFactoryOptions, FromYamlOptions, ReloadOptions } from './factory.js'\n\n// YAML Engine (public API)\nexport {\n evaluateExpression,\n PolicyError,\n BUILTIN_OPERATOR_NAMES,\n BUILTIN_SELECTOR_PREFIXES,\n MAX_REGEX_INPUT,\n} from './yaml-engine/index.js'\nexport type { CustomOperator, CustomSelector } from './yaml-engine/index.js'\nexport {\n compileContracts,\n loadBundle,\n loadBundleString,\n computeHash,\n MAX_BUNDLE_SIZE,\n composeBundles,\n expandMessage,\n validateOperators,\n} from './yaml-engine/index.js'\nexport type {\n CompiledBundle,\n CompileOptions,\n BundleHash,\n ComposedBundle,\n CompositionReport,\n CompositionOverride,\n ObserveContract,\n EvaluateOptions as ExpressionEvaluateOptions,\n} from './yaml-engine/index.js'\n"],"mappings":"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","names":["createHash","realpathSync","fail","realpathSync","createHash","run"]}