;; lib/acl/api.sx — public ACL surface over an implicit current db.
;;
;; Callers load a fact set once, then issue decisions without threading the db
;; through every call. The current db is module state; (acl/load! facts) rebuilds
;; it. This is the boundary the rest of rose-ash imports.

(define acl-current-db nil)

;; Replace the current fact base. Rebuilds the Datalog db under the active
;; ruleset (see lib/acl/engine.sx).
(define
  acl/load!
  (fn
    (facts)
    (do (set! acl-current-db (acl-build-db facts)) acl-current-db)))

;; Ensure a db exists, building an empty one on first use.
(define
  acl-ensure-db!
  (fn
    ()
    (do
      (when
        (= acl-current-db nil)
        (set! acl-current-db (acl-build-db (list))))
      acl-current-db)))

;; Public decision against the current db (pure, no logging).
(define
  acl/permit?
  (fn (subj act res) (acl-permit? (acl-ensure-db!) subj act res)))

;; Decision-with-proof against the current db. See lib/acl/explain.sx.
(define
  acl/explain
  (fn (subj act res) (acl-explain (acl-ensure-db!) subj act res)))

;; Audited decision: logs the outcome to the append-only audit log and returns
;; the boolean. See lib/acl/audit.sx.
(define
  acl/audit
  (fn (subj act res) (acl-audit-decide! (acl-ensure-db!) subj act res)))

;; Recent audited decisions (chronological).
(define acl/audit-tail (fn (n) (acl-audit-tail n)))
