mod: Phase 1 — report schema + policy engine on Prolog, 31/31
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m5s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m5s
Reports → Prolog facts (report/3, classification/2, report_count/2); ordered policy rules compile to policy_action/3 clauses, first match wins via pl-query-one. Decisions carry their proof (matching rule + conditions + evidence). Spam/abuse keyword classification, repeated-report escalation via Prolog join+arithmetic, no-rule→keep default. Registry api + conformance harness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
45
lib/mod/engine.sx
Normal file
45
lib/mod/engine.sx
Normal file
@@ -0,0 +1,45 @@
|
||||
;; lib/mod/engine.sx — decide a report by querying the policy program.
|
||||
;;
|
||||
;; build-program assembles the report's facts plus the compiled policy clauses;
|
||||
;; decide-report runs the Prolog query and returns a decision. A decision is a
|
||||
;; proof, not a bare keyword: it carries the matching rule, the conditions it
|
||||
;; required, the evidence that satisfied them, and the report count — everything
|
||||
;; Phase 2's audit trail needs to persist a "why".
|
||||
|
||||
(define
|
||||
mod/find-rule
|
||||
(fn
|
||||
(rules name)
|
||||
(reduce
|
||||
(fn
|
||||
(acc r)
|
||||
(if (nil? acc) (if (= (mod/rule-name r) name) r acc) acc))
|
||||
nil
|
||||
rules)))
|
||||
|
||||
(define
|
||||
mod/build-program
|
||||
(fn
|
||||
(r count rules)
|
||||
(str (mod/report-facts r count) "\n" (mod/rules->program rules))))
|
||||
|
||||
(define
|
||||
mod/decide-report
|
||||
(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
|
||||
((sol (pl-query-one db (str "policy_action(" id ", Action, Rule)"))))
|
||||
(if
|
||||
(nil? sol)
|
||||
{:action "keep" :proof {:evidence kinds :conditions (list) :rule "none" :count count} :report-id id :rule "none"}
|
||||
(let
|
||||
((rname (dict-get sol "Rule")))
|
||||
(let ((rule (mod/find-rule rules rname))) {:action (mod/rule-action rule) :proof {:evidence kinds :conditions (mod/rule-when rule) :rule rname :count count} :report-id id :rule rname})))))))))
|
||||
Reference in New Issue
Block a user