/** * installPack — opinionated bootstrap for adopters that want sensible * defaults instead of plumbing every sink + conformance check by hand. * * What it does, in order: * * 1. Calls `assertPackConformance(pack)` — fails fast on malformed Packs. * 2. If no MetricsSink is installed, wires `createConsoleMetricsSink()` * and emits a one-time `console.warn` so production deployments do * not silently rely on console output. * 3. Returns the Pack wrapped via `withBasisAudit(...)` so refusal-code * drift records a `basis_code_drift` sink-failure event. * * Adopters who manage their own observability call the lower-level * primitives (`assertPackConformance`, `withBasisAudit`, `setMetricsSink`) * directly. `installPack` is pure convenience — it never installs anything * destructive. */ import type { AuthorityGraph, RecordedAuthoritySnapshot } from "./envelope.js"; import type { PackV0 } from "./pack.js"; /** * 082 — load-time provenance verification result contracts. * * These are the MINIMAL structural shapes `installPack` needs from the * provenance verifiers, declared HERE (in `@adjudicate/core`) so the load path * never takes a build dependency on `@adjudicate/conformance` — which already * depends on `@adjudicate/core` (a `core → conformance` import would be a cycle). * The real verifiers (`verifyPackTrust`, `verifyConfigSeal`) live in conformance * and are INJECTED through `VerifyOnLoadOptions` (the impure shell wires them); * `PackTrustReport` / `ConfigSealReport` are structurally assignable to these. * Kernel-purity holds (§D): verification reads injected snapshots + the live * pack surface only — no IO, no clock, no signing here. */ export interface LoadTrustReport { /** True only when every trust axis passed under the supplied policy. */ readonly trusted: boolean; readonly errors: ReadonlyArray; } export interface LoadSealReport { /** True only when digest + (policy-required) signature both verified. */ readonly verified: boolean; readonly errors: ReadonlyArray; } /** * 082 — `installPack` refuses to install a Pack whose signature/trust or config * seal does not verify (fail-closed, §D-6: a write-path verification failure * ABORTS the install; it never installs an unverified Pack and never fails * open). Behind this option — when `verifyOnLoad` is absent the install path is * byte-identical to pre-082 (only `assertPackConformance` runs), so this is a * non-breaking, opt-in load gate (§7). * * Both verifiers are INJECTED (the shell supplies the conformance functions and * the recorded `seal` / `publicKeyPem` snapshots) so `@adjudicate/core` keeps * zero dependency on `@adjudicate/conformance`. Defaults are STRICT at the load * boundary (§3): trust `policy:"require_signature"` and seal `policy: * "require_signature"`, so an UNSIGNED Pack (no `signature` / no `publicKeyPem` * supplied) fails closed rather than installing unverified (§C: failure → * friction, never bypass). */ export interface VerifyOnLoadOptions { /** * Injected trust verifier — pass `verifyPackTrust` from * `@adjudicate/conformance`. Called over the pack's declarative fingerprint * subset with the strict load-path defaults. A report with `trusted === false` * ABORTS the install. */ readonly verifyPackTrust: (args: { readonly pack: PackFingerprintLike; readonly expectedFingerprint?: string; readonly publicKeyPem?: string; readonly signature?: unknown; readonly policy?: string; }) => LoadTrustReport; /** * Injected seal verifier — pass `verifyConfigSeal` from * `@adjudicate/conformance`. Re-extracts + re-hashes the LIVE pack and checks * it against the injected `seal`. A report with `verified === false` ABORTS * the install. Omit (`seal` absent) to verify trust only. */ readonly verifyConfigSeal?: (pack: unknown, seal: unknown, options: { readonly publicKeyPem?: string; readonly policy?: string; }) => LoadSealReport; /** * The recorded config-seal SNAPSHOT to verify the live pack against (injected * input, §D). Required for seal enforcement; when omitted, only trust is * checked. Under the strict default seal policy, a missing seal cannot be * "verified clean" — it is simply not run (trust still gates the install). */ readonly seal?: unknown; /** Expected fingerprint to additionally pin (optional belt-and-suspenders). */ readonly expectedFingerprint?: string; /** Publisher's PEM-encoded public key. REQUIRED under the strict default. */ readonly publicKeyPem?: string; /** The detached signature over the fingerprint. REQUIRED under the strict default. */ readonly signature?: unknown; /** * Trust policy. Defaults to the STRICT load posture `"require_signature"` (NOT * the library default `best_effort`) so absence of a valid signature refuses * the install (§3). */ readonly trustPolicy?: string; /** * Config-seal policy. Defaults to the STRICT load posture `"require_signature"` * (NOT the library default `require_digest`) so a seal without a verified * signature refuses the install (§3). */ readonly sealPolicy?: string; } /** Minimal declarative-subset shape the injected trust verifier fingerprints. */ export interface PackFingerprintLike { readonly id: string; readonly version: string; readonly contract: string; readonly intents: ReadonlyArray; readonly signals?: ReadonlyArray; readonly basisCodes?: ReadonlyArray; } /** * 082 — thrown when load-time provenance verification fails. Fail-closed: the * install is ABORTED before any sink wiring or snapshot recording, so an * unverified Pack never becomes the live authority (§D-1, §D-6). */ export declare class PackLoadVerificationError extends Error { readonly packId: string; readonly axis: "trust" | "config_seal"; readonly errors: ReadonlyArray; constructor(packId: string, axis: "trust" | "config_seal", errors: ReadonlyArray); } export interface InstallPackOptions { /** * When true (default), `installPack` wires `createConsoleMetricsSink()` * if no sink is currently set, emitting a `console.warn` to flag the * default. Pass false to opt out — tests typically do this. */ readonly installDefaultMetrics?: boolean; /** * When true (default), `installPack` wires `createConsoleLearningSink()` * if no LearningSink is currently set. Same opt-out story as metrics. */ readonly installDefaultLearning?: boolean; /** * When true (default), the returned Pack's policy is wrapped via * `withBasisAudit` so refusal-code drift is observable. Pass false only * if the adopter applies their own decoration. */ readonly auditBasisDrift?: boolean; /** * T4 (#20): allow Packs that ship `policy.default = "EXECUTE"`. Off by * default — `assertPackConformance` throws on EXECUTE-default unless * this opt-in is passed. Read-only Packs (e.g., a "search" or "summary" * pack with no mutating intents) legitimately want this. */ readonly allowDefaultExecute?: boolean; /** * Override for the warn line. Tests inject a vi.fn(); production uses * the default `console.warn`. */ readonly warn?: (message: string) => void; /** * 033 — the authority-graph SNAPSHOT to INJECT into this pack's decisions. * `installPack` is the documented injection seam (no existing guard injection, * no signature check). When supplied, `installPack` content-addresses the graph * (`recordAuthoritySnapshot`) and exposes the RECORDED snapshot on the returned * `InstalledPack.authoritySnapshot`, which the impure audit shell records onto * the `AuditRecord` so the decision is REPLAYABLE (§D-5, invariant #5). * * **Injection seam only — 033 wires NO authority guard** (that is 034) and the * graph rides as an INJECTED STATE/recorded input, NOT a hashed envelope field * (invariant #4 untouched). The pack's `authGuards` are NOT modified here; the * snapshot is recorded, not consulted by any guard. */ readonly authoritySnapshot?: AuthorityGraph; /** * 082 — LOAD-TIME provenance enforcement. When supplied, `installPack` * verifies the Pack's signature/trust (`verifyPackTrust`) and, when a `seal` * is provided, its config seal (`verifyConfigSeal`) BEFORE returning the * `InstalledPack`. A non-verifying report throws `PackLoadVerificationError` * and the Pack does NOT install (fail-closed, §D-6 / §C). Absent ⇒ unchanged * pre-082 behavior (only `assertPackConformance` runs). The verifiers are * INJECTED (from `@adjudicate/conformance`) so the kernel keeps no dependency * on conformance; defaults are STRICT (`require_signature` on both axes). */ readonly verifyOnLoad?: VerifyOnLoadOptions; } export type InstalledDefault = "metrics" | "learning"; export interface InstalledPack { readonly pack: PackV0; readonly installedDefaults: ReadonlyArray; /** * 033 — the RECORDED authority snapshot (graph + content-address) when an * `authoritySnapshot` was injected at install. ABSENT (`undefined`) otherwise, * so non-injecting adopters see no behavioral change. The audit shell records * this onto each `AuditRecord` (via `buildAuditRecord({ authoritySnapshot })`) * so the decision replays bit-identically over the recorded snapshot (§D-5). */ readonly authoritySnapshot?: RecordedAuthoritySnapshot; } export declare function installPack(pack: PackV0, options?: InstallPackOptions): InstalledPack; //# sourceMappingURL=install.d.ts.map