Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
Plans for acl-on-sx (Datalog), flow-on-sx (Scheme), feed-on-sx (APL), mod-on-sx (Prolog), search-on-sx (Haskell). Each is a 4-phase queue sitting on its respective guest language, targeting rose-ash needs: access control, durable workflows, activity feeds, moderation, search. Federation extension in Phase 4 of each (plugs into fed-sx). Briefings for the three loops we're kicking off now: acl-loop, flow-loop, feed-loop. mod-sx and search-sx briefings will follow once the first three have surfaced any shared infrastructure worth extracting to lib/guest/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
103 lines
4.6 KiB
Markdown
103 lines
4.6 KiB
Markdown
# acl-on-sx: Access Control on Datalog
|
||
|
||
rose-ash needs fine-grained, explainable, federation-aware access control. Subjects
|
||
(users, groups, roles, services) × actions (read, edit, comment, moderate, federate)
|
||
× resources (pages, posts, threads, peers). Decisions must come with a trace — not just
|
||
permit/deny, but **why**.
|
||
|
||
Datalog's bottom-up rule engine produces transparent permit/deny chains: the proof tree
|
||
is the audit trail. Inheritance over groups + resource hierarchies is recursive Datalog
|
||
in one rule. Federation extends naturally — fed-sx replicates ACL facts, peers reason
|
||
over the union.
|
||
|
||
End-state: a Datalog-on-SX layer specifically for ACL, with explanation API, audit log,
|
||
and federation extension. Reuses `lib/datalog/` evaluator and term model where possible.
|
||
|
||
## Status (rolling)
|
||
|
||
`bash lib/acl/conformance.sh` → **0/0** (not yet started)
|
||
|
||
## Ground rules
|
||
|
||
- **Scope:** only touch `lib/acl/**` and `plans/acl-on-sx.md`. Do **not** edit `spec/`,
|
||
`hosts/`, `shared/`, `lib/datalog/**`, or other `lib/<lang>/`. You may **import**
|
||
from `lib/datalog/` (its public API in `lib/datalog/datalog.sx`); do **not** copy or
|
||
modify Datalog code.
|
||
- **Shared-file issues** go under "Blockers" with a minimal repro; do not fix here.
|
||
- **SX files:** use `sx-tree` MCP tools only.
|
||
- **Architecture:** thin layer on top of `lib/datalog/`. Define schema, surface API,
|
||
audit + federation hooks. The rule engine itself is Datalog's.
|
||
- **Watch for shared patterns** going into `lib/guest/` — both acl-sx and mod-sx need
|
||
rule-engine plumbing. If you find shared shape, flag it for extraction (don't
|
||
extract yet — wait for mod-sx to start).
|
||
- **Commits:** one feature per commit. Keep Progress log updated and tick boxes.
|
||
|
||
## Architecture sketch
|
||
|
||
```
|
||
ACL declarations (SX) User query
|
||
│ │
|
||
▼ ▼
|
||
lib/acl/schema.sx lib/acl/api.sx
|
||
— subject sorts — (acl/permit? subj act res)
|
||
— resource sorts — (acl/explain subj act res)
|
||
— action sorts — (acl/audit subj act res :allowed?)
|
||
— fact schema │
|
||
│ ▼
|
||
▼ lib/acl/engine.sx
|
||
lib/acl/facts.sx — builds Datalog query
|
||
— actor(id, kind) — invokes lib/datalog/
|
||
— resource(id, kind) — extracts proof tree
|
||
— member_of(actor, group) │
|
||
— child_of(res, parent) ▼
|
||
— grant(actor, act, res) lib/acl/audit.sx
|
||
— deny (actor, act, res) — persistent decision log
|
||
— query API
|
||
```
|
||
|
||
## Phase 1 — Direct grants
|
||
|
||
- [ ] `lib/acl/schema.sx` — sorts: subject {user, group, role, service}, action,
|
||
resource {page, post, thread, peer}
|
||
- [ ] `lib/acl/facts.sx` — `actor`, `resource`, `grant`, `deny` predicates as Datalog
|
||
EDB
|
||
- [ ] `lib/acl/engine.sx` — `(permit? subj act res db)` reduces to Datalog query
|
||
- [ ] `lib/acl/api.sx` — public `(acl/permit? ...)` taking implicit current db
|
||
- [ ] `lib/acl/tests/direct.sx` — 15+ cases: direct grant, missing grant, explicit deny
|
||
- [ ] `lib/acl/scoreboard.{json,md}` baseline
|
||
- [ ] `lib/acl/conformance.sh` runs the suite
|
||
|
||
## Phase 2 — Inheritance
|
||
|
||
- [ ] `member_of(actor, group)` chain — group grants apply to members (transitive)
|
||
- [ ] `child_of(res, parent)` chain — parent grants apply to children (transitive)
|
||
- [ ] role expansion — role contains list of (action, resource) tuples
|
||
- [ ] deny-overrides — explicit deny wins over inherited allow
|
||
- [ ] `lib/acl/tests/inherit.sx` — 25+ cases: nested groups, deep resource trees,
|
||
conflict resolution, deny precedence
|
||
- [ ] document the deny-overrides choice in plan
|
||
|
||
## Phase 3 — Explanation + audit
|
||
|
||
- [ ] `(acl/explain subj act res)` → `{:allowed? T :proof <tree>}`
|
||
- [ ] proof tree extracts from Datalog's derivation
|
||
- [ ] `lib/acl/audit.sx` — append-only decision log (in-memory + serializer for disk)
|
||
- [ ] `(acl/audit-tail n)` for recent decisions
|
||
- [ ] `lib/acl/tests/explain.sx` — proof correctness, audit completeness
|
||
|
||
## Phase 4 — Federation
|
||
|
||
- [ ] peer trust facts — `peer(addr, kind)`, `trust(peer, level)`
|
||
- [ ] delegated grants — `delegate(peer, actor, action, resource)`
|
||
- [ ] cross-instance permit chain — query asks local + queries trusted peers via fed-sx
|
||
- [ ] revocation propagation — fact retraction across federation
|
||
- [ ] `lib/acl/tests/fed.sx` — federated grant chains (mock fed-sx transport in tests)
|
||
|
||
## Progress log
|
||
|
||
(loop fills this in)
|
||
|
||
## Blockers
|
||
|
||
(loop fills this in)
|