;; lib/mod/batch.sx — batch triage + corpus analytics. ;; ;; Operational layer: decide a whole queue of reports at once, summarize the ;; outcomes by action, and measure which rules actually fire across a corpus. ;; mod/never-fired is the empirical complement to lint's static unreachable check ;; (Ext 5): lint finds rules that CAN'T fire by structure; never-fired finds rules ;; that DIDN'T fire on real data. (define mod/decide-batch (fn (reports rules) (map (fn (r) (mod/decide-report r reports rules)) reports))) (define mod/count-action (fn (decisions action) (reduce (fn (acc d) (if (= (get d :action) action) (+ acc 1) acc)) 0 decisions))) (define mod/action-histogram (fn (decisions) {:keep (mod/count-action decisions "keep") :remove (mod/count-action decisions "remove") :escalate (mod/count-action decisions "escalate") :hide (mod/count-action decisions "hide") :ban (mod/count-action decisions "ban")})) (define mod/rule-fire-count (fn (decisions rule-name) (reduce (fn (acc d) (if (= (get d :rule) rule-name) (+ acc 1) acc)) 0 decisions))) (define mod/rule-coverage (fn (reports rules) (let ((decisions (mod/decide-batch reports rules))) (map (fn (rule) {:rule (mod/rule-name rule) :fired (mod/rule-fire-count decisions (mod/rule-name rule))}) rules)))) (define mod/never-fired (fn (reports rules) (reduce (fn (acc c) (if (= (get c :fired) 0) (append acc (list (get c :rule))) acc)) (list) (mod/rule-coverage reports rules))))