When introducing or changing an API seam (hooks, callback payloads, lifecycle state transitions), require an explicit, end-to-end, type-safe contract that matches implementation and documentation.

Checklist:

Example pattern (typed settlement wrapper):

type UserInputSettlementReason =
  | 'resolved_outside_card'
  | 'request_cancelled'
  | 'run_cancelled'
  | 'expired';

function setSettlementReason(signal: AbortSignal, reason: UserInputSettlementReason) {
  // avoid writing to any-typed fields directly; centralize the mapping
  (signal as any).__settlementReason = reason;
}

Example contract sketch (adapter-facing context):

interface ChannelUserInputRequestContext {
  requestId: string;
  sessionId: string;
  runId: string;
  target: SessionTarget;
  ownerId: string;
  request: PermissionRequestEvent['request'];
  settlementSignal: AbortSignal;
  respond(response: { /* RequestPermissionResponse + optional answers */ }): Promise<boolean>;
}

If any of the above can’t be satisfied, treat it as an API design bug: either the contract is incomplete, the correlation is not end-to-end, the semantics are not type-safe, or the documentation/API surface are out of sync.