acl: hardening suite (+25) — diamonds, cycles, validation, audit save/restore
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
New adversarial/cross-phase coverage: diamond resource+group hierarchies (deny wins per path), chain inheritance + leaf deny, cycle termination, multi-peer delegation, fact validation, audit snapshot/restore round-trip. Adds acl-validate-facts/acl-facts-valid? (schema) and acl-audit-snapshot/ restore!/copy (audit). Fixed acl-audit-restore! rebuilding the live log via map (append! silently no-ops on map-derived lists). Suite is prover-free: a substrate JIT bug loops the recursive proof reconstructor on deep chains in warm processes (documented in Blockers); acl-permit? is unaffected. 145/145. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,12 +3,23 @@
|
||||
;; Every decision routed through acl-audit-decide! is appended to an in-memory
|
||||
;; log with a monotonic sequence number (no wall-clock — deterministic and
|
||||
;; testable; a host can stamp time at the serializer boundary). The log is
|
||||
;; append-only: there is no mutate or delete, only append, tail, clear, and
|
||||
;; serialize-for-disk.
|
||||
;; append-only: there is no mutate or delete, only append, tail, clear,
|
||||
;; snapshot/restore, and serialize-for-disk.
|
||||
|
||||
(define acl-audit-log (list))
|
||||
(define acl-audit-seq 0)
|
||||
|
||||
;; Copy a list into a fresh, append!-able list. `map`/`rest`-derived lists are
|
||||
;; NOT extensible by append! in this runtime (it silently no-ops), so the live
|
||||
;; log must always be a list built with `list` + `append!`.
|
||||
(define
|
||||
acl-audit-copy
|
||||
(fn
|
||||
(xs)
|
||||
(let
|
||||
((fresh (list)))
|
||||
(do (for-each (fn (e) (append! fresh e)) xs) fresh))))
|
||||
|
||||
(define
|
||||
acl-audit-clear!
|
||||
(fn
|
||||
@@ -57,8 +68,25 @@
|
||||
(xs k)
|
||||
(if (<= k 0) xs (acl-audit-drop (rest xs) (- k 1)))))
|
||||
|
||||
;; Structured snapshot for save/restore — a {:seq :entries} value carrying a
|
||||
;; copy of the log (so later appends don't mutate a held snapshot).
|
||||
(define acl-audit-snapshot (fn () {:seq acl-audit-seq :entries (acl-audit-copy acl-audit-log)}))
|
||||
|
||||
;; Replace the live log from a snapshot. Restores both entries and the seq
|
||||
;; counter so subsequent records continue numbering correctly. The log is
|
||||
;; rebuilt as a fresh append!-able list (see acl-audit-copy).
|
||||
(define
|
||||
acl-audit-restore!
|
||||
(fn
|
||||
(snap)
|
||||
(do
|
||||
(set! acl-audit-log (acl-audit-copy (get snap :entries)))
|
||||
(set! acl-audit-seq (get snap :seq))
|
||||
nil)))
|
||||
|
||||
;; Serialize the whole log to a disk-ready string: one record per line,
|
||||
;; "seq\tsubj\tact\tres\tallowed?". A host writes this; reload is out of scope.
|
||||
;; "seq\tsubj\tact\tres\tallowed?". A host writes this; structured reload is via
|
||||
;; snapshot/restore.
|
||||
(define
|
||||
acl-audit-serialize
|
||||
(fn
|
||||
|
||||
Reference in New Issue
Block a user