;; lib/mod/severity.sx — "strictest-wins" decision strategy.
;;
;; The default engine resolves precedence by rule ORDER (first proven clause wins,
;; via pl-query-one). Some policies instead want the HARSHEST applicable sanction
;; regardless of order. mod/decide-strictest collects every rule that proves
;; (pl-query-all) and picks the highest-severity action. Same decision shape as
;; the engine, plus :strategy. Built over the engine's helpers; engine untouched.

(define
  mod/action-severity
  (fn
    (action)
    (cond
      ((= action "ban") 4)
      ((= action "remove") 3)
      ((= action "hide") 2)
      ((= action "escalate") 1)
      (true 0))))

(define
  mod/strictest-sol
  (fn
    (sols)
    (reduce
      (fn
        (acc s)
        (if
          (nil? acc)
          s
          (if
            (<
              (mod/action-severity (dict-get acc "Action"))
              (mod/action-severity (dict-get s "Action")))
            s
            acc)))
      nil
      sols)))

(define
  mod/decide-strictest
  (fn
    (r reports rules)
    (let
      ((count (mod/report-count (mod/report-about r) reports))
        (kinds (mod/classify-keywords r))
        (id (mod/report-id r)))
      (let
        ((program (mod/build-program r count rules)))
        (let
          ((db (pl-load program)))
          (let
            ((sols (pl-query-all db (str "policy_action(" id ", Action, Rule)"))))
            (let
              ((best (mod/strictest-sol sols)))
              (if
                (nil? best)
                {:action "keep" :proof {:goals (list) :evidence kinds :conditions (list) :rule "none" :count count} :report-id id :rule "none" :strategy "strictest"}
                (let
                  ((rule (mod/find-rule rules (dict-get best "Rule"))))
                  {:action (mod/rule-action rule) :proof {:goals (mod/proof-goals db id (mod/rule-when rule)) :evidence kinds :conditions (mod/rule-when rule) :rule (mod/rule-name rule) :count count} :report-id id :rule (mod/rule-name rule) :strategy "strictest"})))))))))
