; feed/acl — per-viewer visibility filtering. The same candidate stream yields ; different timelines for different viewers, so ACL is applied per request and ; pre-ACL timelines are never cached. ; ; permit? is injected: (permit? viewer activity) -> bool. Wire a real acl-sx ; predicate here; feed/permit-acl? is a self-contained default that reads an ; optional :visible-to allowlist on the activity. ; ; Requires: lib/feed/normalize.sx, lib/feed/stream.sx, lib/feed/fanout.sx ; (feed/-elem?), lib/feed/rank.sx (feed/top). ; default permit: actor always sees own activity; absent/nil :visible-to is ; public; otherwise viewer must be in the allowlist. (define feed/permit-acl? (fn (viewer a) (or (equal? viewer (get a :actor)) (let ((allowed (get a :visible-to nil))) (if (= allowed nil) true (feed/-elem? viewer allowed)))))) (define feed/permit-public? (fn (viewer a) true)) ; filter a stream to what viewer may read (define feed/visible (fn (stream viewer permit?) (feed/filter stream (fn (a) (permit? viewer a))))) ; the capstone: candidate stream -> ACL for viewer -> rank -> top-N (define feed/timeline (fn (stream viewer permit? score-fn n) (feed/top (feed/visible stream viewer permit?) score-fn n)))