;; lib/mod/tests/offenders.sx — Ext 7: repeat-offender escalation. (define mod-off-count 0) (define mod-off-pass 0) (define mod-off-fail 0) (define mod-off-failures (list)) (define mod-off-test! (fn (name got expected) (begin (set! mod-off-count (+ mod-off-count 1)) (if (= got expected) (set! mod-off-pass (+ mod-off-pass 1)) (begin (set! mod-off-fail (+ mod-off-fail 1)) (append! mod-off-failures (str name "\n expected: " expected "\n got: " got))))))) ;; ── sanction? predicate ── (mod-off-test! "hide is a sanction" (mod/sanction? "hide") true) (mod-off-test! "remove is a sanction" (mod/sanction? "remove") true) (mod-off-test! "ban is a sanction" (mod/sanction? "ban") true) (mod-off-test! "keep is not a sanction" (mod/sanction? "keep") false) (mod-off-test! "escalate is not a sanction" (mod/sanction? "escalate") false) ;; ── repeat-offender escalation over the audit log ── (mod/reset!) (mod/report "u1" "spammer" "this is spam") (mod/report "u2" "spammer" "buy now offer") (mod/report "u3" "spammer" "click here free money") (mod/report "u4" "innocent" "fine post") (mod-off-test! "no sanctions before any decision" (mod/subject-sanctions "spammer") 0) (define mod-off-d1 (mod/decide-escalating "r1" 2)) (mod-off-test! "first spam → hide (0 priors)" (get mod-off-d1 :action) "hide") (mod-off-test! "one sanction recorded" (mod/subject-sanctions "spammer") 1) (define mod-off-d2 (mod/decide-escalating "r2" 2)) (mod-off-test! "second spam → hide (1 prior, below k=2)" (get mod-off-d2 :action) "hide") (mod-off-test! "two sanctions recorded" (mod/subject-sanctions "spammer") 2) (define mod-off-d3 (mod/decide-escalating "r3" 2)) (mod-off-test! "third spam → ban (2 priors ≥ k)" (get mod-off-d3 :action) "ban") (mod-off-test! "ban decision names repeat-offender rule" (get mod-off-d3 :rule) "repeat-offender-ban") (mod-off-test! "ban proof records prior sanction count" (get (get mod-off-d3 :proof) :prior-sanctions) 2) ;; ── different subjects accumulate independently ── (define mod-off-d4 (mod/decide-escalating "r4" 2)) (mod-off-test! "innocent keep → not escalated" (get mod-off-d4 :action) "keep") (mod-off-test! "innocent has no sanctions" (mod/subject-sanctions "innocent") 0) (mod-off-test! "repeat-offender? true for spammer at k=2" (mod/repeat-offender? "spammer" 2) true) (mod-off-test! "repeat-offender? false for innocent at k=1" (mod/repeat-offender? "innocent" 1) false) ;; ── non-sanction decisions are never upgraded to ban ── ;; r5 is a clean post, but it is the 4th report about "spammer", so the ;; repeated-report rule escalates it. escalate is not a sanction, so it passes ;; through decide-escalating unchanged (never becomes :ban). (mod/report "u5" "spammer" "a perfectly fine post") (define mod-off-d5 (mod/decide-escalating "r5" 1)) (mod-off-test! "non-sanction (escalate) decision is not upgraded to ban" (get mod-off-d5 :action) "escalate") (mod-off-test! "decide-escalating unknown id → nil" (mod/decide-escalating "r99" 2) nil) (define mod-offenders-tests-run! (fn () {:failures mod-off-failures :total mod-off-count :passed mod-off-pass :failed mod-off-fail}))