Files
rose-ash/lib/mod/trace.sx
giles 3764b62206
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 49s
mod: Ext 9 — policy dry-run trace diagnostics, 247/247
mod/trace-rules evaluates a report against every rule, returning each rule's
proved/unproved status + goal-by-goal derivation (an unproved rule shows which
goal failed). mod/first-proved = winner (matches engine precedence, cross-checked),
mod/proved-rules the firing set, mod/trace-report a [fires]/[ - ] rendering.
Answers 'why didn't my rule fire?' without instrumenting the engine. +15 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:48:44 +00:00

57 lines
1.6 KiB
Plaintext

;; lib/mod/trace.sx — policy dry-run diagnostics.
;;
;; decide-report returns the winning rule; a policy author debugging "why didn't
;; my rule fire?" needs the whole picture. mod/trace-rules evaluates a report
;; against every rule and reports each rule's proved/unproved status plus its
;; goal-by-goal derivation — so an unproved rule shows exactly which goal failed.
;; The winner is the first proved rule (same precedence as the engine).
(define
mod/trace-rules
(fn
(r reports rules)
(let
((count (mod/report-count (mod/report-about r) reports))
(id (mod/report-id r)))
(let
((db (pl-load (mod/build-program r count rules))))
(let
((proved-names (map (fn (s) (dict-get s "Rule")) (pl-query-all db (str "policy_action(" id ", _, Rule)")))))
(map
(fn (rule) (let ((nm (mod/rule-name rule))) {:proved (mod/member? nm proved-names) :goals (mod/proof-goals db id (mod/rule-when rule)) :action (mod/rule-action rule) :rule nm}))
rules))))))
(define
mod/first-proved
(fn
(trace)
(reduce
(fn (acc t) (if (nil? acc) (if (get t :proved) t acc) acc))
nil
trace)))
(define
mod/proved-rules
(fn
(trace)
(reduce
(fn
(acc t)
(if (get t :proved) (append acc (list (get t :rule))) acc))
(list)
trace)))
(define
mod/trace-row
(fn
(t)
(str
(if (get t :proved) "[fires] " "[ - ] ")
(get t :rule)
" → "
(get t :action))))
(define
mod/trace-report
(fn (trace) (mod/join-with "\n" (map mod/trace-row trace))))