import type { V2Delegation } from '../../types.js'; import type { DenialReason } from '../types.js'; export type BindingRailName = 'ap2' | 'x402' | 'stripe-issuing' | 'acp' | 'mpp'; /** * The minimal common surface every binding adapter exposes for * Tier-2 conformance. `resolveSpendCap` returns the spend cap a * V2Delegation imposes in minor currency units, or null when no cap * is configured. `mapDenialToFoundation` projects a rail-specific * denial reason string into the closed foundation taxonomy, returning * null for unrecognized inputs. * * Wrappers are thin shims over the rail's existing exports. The * harness ships built-in wrappers in BUILTIN_BINDING_ADAPTERS; rail * sources stay unchanged. */ export interface BindingRailAdapter { name: BindingRailName; resolveSpendCap(delegation: V2Delegation): number | null; mapDenialToFoundation(railSpecificReason: string): DenialReason | null; } export interface ConformanceFixtureScenario { id: string; description: string; /** A V2Delegation. Each rail's resolveSpendCap is invoked against * this; the result must equal expected_cap_minor_units. */ delegation: V2Delegation; expected_cap_minor_units: number | null; } export interface DenialFixtureScenario { id: string; description: string; /** Rail-specific code the rail's mapping function consumes. */ rail_specific_reason: string; /** The closed-taxonomy foundation reason the rail-specific code * must project to. */ expected_foundation_reason: DenialReason; } export interface DeterminismFixtureScenario { id: string; description: string; delegation: V2Delegation; expected_cap_minor_units: number | null; } export interface BindingFixtureSet { rail_name: BindingRailName; schema_version: string; conformance: ConformanceFixtureScenario[]; denials: DenialFixtureScenario[]; determinism: DeterminismFixtureScenario[]; } export type Tier2Invariant = 'field_name_resolution' | 'denial_round_trip' | 'resolver_determinism' | 'cross_rail_byte_parity'; export interface BindingScenarioReport { rail_name: BindingRailName; scenario_id: string; invariant: Tier2Invariant; pass: boolean; detail?: string; } export interface BindingConformanceReport { schema_version: string; started_at: string; finished_at: string; total: number; passed: number; failed: number; all_pass: boolean; scenarios: BindingScenarioReport[]; } export interface RunBindingConformanceOpts { /** Throw on first byte-parity violation. Default false (audit mode * collects every result). Tests pass true to fail fast. */ strict?: boolean; } /** All five built-in wrappers in fixed order. Tests typically pass * this list verbatim to runBindingConformance(). */ export declare const BUILTIN_BINDING_ADAPTERS: readonly BindingRailAdapter[]; /** * Run the Tier-2 binding-adapter conformance harness. * * For each rail's fixture set: * - Conformance scenarios: invoke resolveSpendCap, assert numeric * equality with expected_cap_minor_units, and record canonical * JSON bytes for the cross-rail byte-parity pass. * - Denial scenarios: invoke mapDenialToFoundation, assert the * result equals expected_foundation_reason and lies in the closed * foundation taxonomy. * - Determinism scenarios: invoke resolveSpendCap twice and assert * byte-identical canonical JSON across the two calls. * * After per-rail passes, the harness folds the conformance results * into a cross-rail byte-parity check: for each conformance scenario * id present in every rail's fixture set, the canonical JSON of the * resolved cap MUST be byte-identical across all rails. * * @param adapters Wrappers to test. Pass BUILTIN_BINDING_ADAPTERS * to cover the five shipped rails. * @param fixtures Map keyed by rail_name; each value is the * rail's fixture set. * @param opts.strict Throw on first failure. Default false. */ export declare function runBindingConformance(adapters: readonly BindingRailAdapter[], fixtures: Readonly>, opts?: RunBindingConformanceOpts): BindingConformanceReport; //# sourceMappingURL=binding-harness.d.ts.map