A provider-neutral harness stabilizes business lifecycle and control contracts while adapters translate to each SDK. Normalize run requests, events, policy, budgets, checkpoints, and outcomes; preserve provider-native handoffs, built-in tools, sessions, and traces as typed extensions. Portability means controlled substitution and migration, not pretending every runtime is identical.
You will define the harness interfaces that SupportOps depends on and draw the boundary between portable controls and provider capabilities.
Add explicit contracts for ToolSpec, ToolResult, PolicyDecision, Budget, Checkpoint, and Evaluator. Keep Any at a serialization boundary only; domain outputs should be typed.
Represent these through extension objects with versioned schemas rather than discarding them.
Build a fake adapter that emits deterministic events. Run the same harness contract tests against the fake, OpenAI, and Claude adapters: start, tool proposal, approval pause, resume, limit, cancellation, and failure.
Failure injection: Have an adapter emit run.completed twice or skip sequence numbers. The harness must reject the invalid lifecycle rather than corrupt the outcome.
Write a versioned adapter capability manifest so orchestration can request required features and fail clearly when a provider lacks them.