/** * Denial tracking infrastructure for permission classifiers. * Tracks consecutive denials and total denials to determine * when to fall back to prompting. */ export type DenialTrackingState = { consecutiveDenials: number totalDenials: number } export const DENIAL_LIMITS = { maxConsecutive: 3, maxTotal: 20, } as const export function createDenialTrackingState(): DenialTrackingState { return { consecutiveDenials: 0, totalDenials: 0, } } export function recordDenial(state: DenialTrackingState): DenialTrackingState { return { ...state, consecutiveDenials: state.consecutiveDenials + 1, totalDenials: state.totalDenials + 1, } } export function recordSuccess(state: DenialTrackingState): DenialTrackingState { if (state.consecutiveDenials === 0) return state // No change needed return { ...state, consecutiveDenials: 0, } } export function shouldFallbackToPrompting(state: DenialTrackingState): boolean { return ( state.consecutiveDenials >= DENIAL_LIMITS.maxConsecutive || state.totalDenials >= DENIAL_LIMITS.maxTotal ) }