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:
runId) must be carried through the shared event/callback payload chain, not stored only in adapter-private state.AbortSignal.reason (typed as any in practice). Route settlement through a typed helper/callback so misspellings can’t compile.stopped event), require an explicit mapping table or explicit statement of how the state is derived.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.