Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 55s
(:reporters-at-least N) compiles to setof(Br, report(_, Br, Sr), Bsr), length(Bsr, Nr), Nr >= N — counts distinct reporters, not raw reports. mod/decide-quorum asserts every report's report/3 fact (base engine scopes to the decided report) so Prolog can aggregate reporters. One user filing 3 reports stays :keep under quorum while the count rule escalates. Own suite. +9 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.7 KiB
Plaintext
41 lines
1.7 KiB
Plaintext
;; lib/mod/quorum.sx — quorum decisions over distinct reporters (anti-brigade).
|
|
;;
|
|
;; The base engine asserts only the decided report's report/3 fact, so it can't
|
|
;; reason about WHO reported a subject. The quorum engine additionally asserts
|
|
;; every report's report/3 fact (via link's rel-facts), letting a rule require N
|
|
;; *distinct* reporters with `setof`/`length` — so one user filing many reports
|
|
;; does not manufacture consensus. Same decision shape as the base engine, plus
|
|
;; :strategy "quorum".
|
|
|
|
(define
|
|
mod/build-quorum-program
|
|
(fn
|
|
(r count reports rules)
|
|
(str
|
|
(mod/report-rel-facts reports)
|
|
"\n"
|
|
(mod/report-facts r count)
|
|
"\n"
|
|
(mod/rules->program rules))))
|
|
|
|
(define
|
|
mod/decide-quorum
|
|
(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-quorum-program r count reports rules)))
|
|
(let
|
|
((db (pl-load program)))
|
|
(let
|
|
((sol (pl-query-one db (str "policy_action(" id ", Action, Rule)"))))
|
|
(if
|
|
(nil? sol)
|
|
{:action "keep" :proof {:goals (list) :evidence kinds :conditions (list) :rule "none" :count count} :report-id id :rule "none" :strategy "quorum"}
|
|
(let
|
|
((rule (mod/find-rule rules (dict-get sol "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 "quorum"}))))))))
|