# mod-on-sx: Moderation on Prolog

rose-ash needs moderation infrastructure: reports flagged by users, automated
classifications (spam, abuse), tiered escalation (auto → human → appeal), audit
trails. Each decision is the conclusion of a backtracking search over evidence and
policy rules — exactly what Prolog does.

Where acl-sx says "may this happen?", mod-sx says "should this stay?" The former is
a positive decision (proof of grant); the latter often a negative one (proof of
violation), and policy chains naturally backtrack: if the first rule doesn't apply,
try the next.

End-state: a Prolog-on-SX layer for moderation policy declaration and evaluation,
with persistent report lifecycle, audit log, escalation state machine, and
federation extension.

## Status (rolling)

`bash lib/mod/conformance.sh` → **0/0** (not yet started)

## Ground rules

- **Scope:** only touch `lib/mod/**` and `plans/mod-on-sx.md`. Do **not** edit
  `spec/`, `hosts/`, `shared/`, `lib/prolog/**`, or other `lib/<lang>/`. You may
  **import** from `lib/prolog/` (public API in `lib/prolog/prolog.sx`); do **not**
  modify Prolog.
- **Shared-file issues** go under "Blockers" with a minimal repro; do not fix here.
- **SX files:** use `sx-tree` MCP tools only.
- **Architecture:** policies are Prolog rules over `report(...)` and `evidence(...)`
  facts. Decisions are query results. Proof trees become audit records. The state
  machine for report lifecycle is separate (an SX module on top).
- **Shared with acl-sx:** rule-engine plumbing may be liftable into `lib/guest/`.
  Watch for it; flag in Progress log but do not extract until both subsystems are
  past Phase 2.
- **Commits:** one feature per commit. Keep Progress log updated and tick boxes.

## Architecture sketch

```
Report                                  Decision
  {:by :about :reason :at}                {:action :proof :next-state}
        │                                       ▲
        ▼                                       │
lib/mod/schema.sx                       lib/mod/engine.sx
  — report/4, evidence/2,                 — query Prolog with report fact
    classification/3 predicates             — extract proof tree
        │                                       ▲
        ▼                                       │
lib/mod/policy.sx                       lib/mod/lifecycle.sx
  — rule syntax → Prolog                  — state machine
  — action heads:                         — open → triaged → decided
    {:keep :hide :remove                  — appeal handling
     :escalate :ban}                            │
        │                                       ▼
        ▼                                lib/mod/audit.sx
lib/mod/api.sx                            — append-only decision log
  — (mod/report ...)                      — proof tree persistence
  — (mod/decide report)                   — query API
  — (mod/appeal id)
        │
        ▼
lib/mod/fed.sx
  — cross-instance reports via fed-sx
  — decision sharing / trust model
```

## Phase 1 — Report representation + simple policy

- [ ] `lib/mod/schema.sx` — `report(id, by, about, reason)`, `evidence(id, kind, val)`,
  `policy-action(report, action)` predicates as Prolog facts/rules
- [ ] `lib/mod/policy.sx` — rule declarations: `(defrule action :when conditions)`
  desugars to Prolog clause
- [ ] `lib/mod/engine.sx` — `(decide report-id)` runs Prolog query, returns first
  matching action
- [ ] `lib/mod/api.sx` — `(mod/report by about reason)`, `(mod/decide id)`
- [ ] `lib/mod/tests/decide.sx` — 15+ cases: spam keyword → hide, repeated reports →
  escalate, no rule matches → keep
- [ ] `lib/mod/scoreboard.{json,md}`
- [ ] `lib/mod/conformance.sh`

## Phase 2 — Evidence + audit trail

- [ ] evidence accumulation — additional facts asserted before query
- [ ] proof tree from Prolog derivation tree
- [ ] `lib/mod/audit.sx` — append-only log (decision + proof + evidence snapshot)
- [ ] `(mod/audit id)` retrieval
- [ ] `lib/mod/tests/audit.sx` — proof correctness, trail completeness

## Phase 3 — Escalation + lifecycle state machine

- [ ] state machine: `:open → :triaged → :decided → :appealed → :final`
- [ ] auto-tier: first-pass rules decide quick cases
- [ ] human-tier: rules that emit `:escalate` move to next state
- [ ] appeal: re-runs with appeal evidence, may override prior decision
- [ ] `(mod/appeal id new-evidence)` API
- [ ] `lib/mod/tests/escalation.sx` — full lifecycle traversal cases

## Phase 4 — Federation

- [ ] cross-instance reports — peer raises report about local content (or vice versa)
- [ ] decision sharing — actions taken locally propagate to peers via fed-sx
- [ ] trust model — peer's decision is advisory unless `(trust peer :mod)` is granted
- [ ] revocation — undo applied moderation if proof was invalidated
- [ ] `lib/mod/tests/fed.sx` — federated decision chains (mock fed-sx in tests)

## Progress log

(loop fills this in)

## Blockers

(loop fills this in)
