# Sekhmet: Trust, Safety, Child-Protection & Anti-Cheat

Sekhmet is the lion-headed floor under V7 (Mawu): the set of platform-central
defenses that make a _creator republic_ survivable. Because Mawu lets community
operators run their own authoritative realms and ship **executable** UGC — real
WASM, not just data — the safety surface is not a feature, it is a precondition.
A community operator can write the rules of their realm, but a community
operator must never run an age check, hold a biometric, decide what counts as
CSAM, or be the authority that detects a cheater on the node they themselves
host. Sekhmet's governing rule, stated in the monolith, is therefore blunt:
**all of this is platform-central, never realm-delegated.** The scan that
decides whether an artifact is ever served, the perceptual-hash match against
known-abuse databases, the grooming classifier, the age band, the cheater
verdict — every one of them lives above the trust boundary the
[Ixchel sandbox](./ixchel-modding-runtime-and-wasm-sandbox.md) and the realm
protocol enforce, and none of them are reachable from realm code.

This page is the deep companion to the monolith's "Sekhmet — Trust, Safety, and
Child-Protection Architecture" and "Anti-Cheat and Client Integrity" sections.
The throughline is that V7 ships these defenses the same way it ships its
sandbox and its netcode: as real, deterministic, CI-gated Rust, with the
_integrations that need a vendor, a model, or a live network_ drawn as honest
seams rather than faked. The section hub is
[../V7_ARCHITECTURE.md](../V7_ARCHITECTURE.md).

## What ships, honestly

The honest split mirrors Ixchel's: the **safety logic and its adversarial evals
are real and green; the live intake-and-serve daemon and the proprietary vendor
models are the seams.**

- **Sekhmet is a real, native Rust crate, not a slide.**
  `apps/v7/sekhmet-scanner/src/lib.rs` is a single ~6,009-line crate whose only
  dependencies are `sha2 = "0.10.9"` and `hmac = "0.12.1"` (`Cargo.toml`) — so
  every hash, signature, and lock pin below is computed for real. It carries
  fifteen integration tests covering malware, supply-chain, sandbox-tier, CSAM
  hash, novel-CSAM classification, grooming, NCII, age assurance, minor
  protection, the Sentinel longitudinal detector, the three-layer moderation
  pipeline, contextual reports, and an incident-response drill. Run directly,
  **all 15 pass** (`cargo test -p sekhmet-scanner` → `15 passed; 0 failed`). Six
  of those evals are wired to CI as named adversarial gates — `malware-corpus`,
  `csam-hash`, `grooming`, `minor-protection`, plus `sandbox-escape` and
  `anticheat` from the realm server
  (`scripts/v7/verify-adversarial-eval-gates.mjs`).
- **Where a defense needs a licensed model, it is a deterministic stand-in with
  the real seam named — not a fake result.** With only `sha2`/`hmac` on hand,
  `compute_csam_perceptual_hashes` (`:1753`) derives deterministic, algorithm-
  labeled digests that stand in for the proprietary **PhotoDNA/PDQ** perceptual
  hashers; the novel-CSAM (`:1894`) and grooming (`:2022`) classifiers are
  signal-weighted scorers over labeled markers, standing in for the licensed
  **Thorn Safer / Project Artemis** ML models. What is _real_ is everything
  around the model: the algorithm/source taxonomy, the block-before-serve
  decision, the human-review routing, and the precision/recall eval that would
  fail on a regression. The facial-age **vendor** is an injected input
  (`FacialAgeEstimateInput`), not a call Sekhmet fakes.
- **The shared trust-safety plane is real, and Sekhmet names its seams.** The
  monolith says Mawu _reuses_ the platform's Aphrodite/Kuanyin/Themis plane, and
  those packages exist and are implemented: `libs/aphrodite/age-verification`
  (`AgeVerificationService` with a provider registry, `service.ts:93`),
  `apps/lilith/svc-ai/src/csam-protection` (a 114 KB `HashMatchingAgent` wired
  to PhotoDNA/Thorn/IWF/NCMEC endpoints, `csam-protection-service.ts:67`),
  `libs/kuanyin/community-harmony/src/raid-defense.ts`, and
  `libs/themis/privacy/src/v2-data-subject-rights.ts` (GDPR Art. 15/17). The
  Rust scanner does not `import` these TypeScript packages — exactly as
  `moremi-realm-server` reimplements `forge-*` natively — but it routes to the
  same seams by name: high-risk content goes to the `kuanyin-human-review` queue
  (`:2138`) and contested removals to a **Themis DSA appeal** (`:2300`).
- **The live daemon is the open boundary.** `run_service` (`:1271`) today serves
  only a readiness/health document; the network listener that accepts a real
  creator upload, scans it, and streams cleared bytes to the CDN is the
  integration target the monolith enumerates. Treat the byte-level mechanics as
  proven and the production wiring as the remaining seam.

## The Sekhmet trust & safety architecture

### The ingest gate: malware scan and the distribution lock

Nothing reaches a client unscanned. `scan_artifact` (`:3461`) classifies an
uploaded artifact into a `ScanVerdict` over signature and heuristic findings,
and `evaluate_distribution_gate` (`:3536`) refuses to emit a fetchable
`DistributionGateDecision` for anything but a clean scan — the test
`distribution_gate_requires_a_clean_scan_before_fetch` pins that order.
`run_malware_corpus_eval` (`:3491`) drives a hostile corpus of known-bad
artifacts and reports a detection rate against a target, the body of the
`malware-corpus` CI gate.

Supply-chain integrity is the second half of the gate, and it is the same
content-addressing primitive the Ixchel content store uses, lifted to the
publish path. `build_content_addressed_artifact` (`:1275`) hashes content plus
its full dependency closure; `build_pinned_lock_file` (`:1364`) freezes the
result; `sign_artifact_manifest` / `verify_signed_artifact_manifest`
(`:1404`/`:1426`) sign and check it with **real HMAC-SHA256**; and
`evaluate_supply_chain_publish` (`:1452`) requires an `AccountStepUpReceipt`
(`:266`) on **re-publish** — the _fractureiser_ defense, where a compromised
maintainer account cannot silently swap a trusted dependency. The test
`supply_chain_pinning_changes_hashes_for_dependency_swap_and_requires_step_up`
proves a swapped dependency changes the artifact hash _and_ trips the step-up.
When something does slip, `run_incident_response_drill` (`:1647`) exercises the
playbook — suspend approvals, quarantine the exact realms pinning a flagged
artifact by content hash, recall, report — verified by
`incident_response_drill_quarantines_exact_realms_pinning_flagged_artifact`.

## Child protection — the highest bar

Child safety is where Sekhmet is most fully built out, because it is the bar a
platform holder refuses to ship without. Every check here is platform-central; a
realm operator is never the CSAM-scanning authority.

### CSAM detection: perceptual-hash match before any serve

`compute_csam_perceptual_hashes` (`:1753`) renders the right hash family per
asset kind: **PhotoDNA + PDQ** for images, **CSAI Match** for video, and — the
3D-native problem the monolith flags as open — **rendered-2D views** of textures
and meshes hashed with `Rendered2dPhotoDna`/`Rendered2dPdq`.
`scan_csam_hash_ingest` (`:1806`) matches those against a known-hash set sourced
from NCMEC-class databases and returns `CsamIngestDecision::Blocked` with
`serve_allowed = false` the instant any hash matches — the artifact is stopped
_before_ it can be fetched, never after. `run_csam_hash_eval` (`:1855`) measures
the detection rate over a synthetic known-hash corpus; its test asserts a 100%
match "before any serve," the `csam-hash` gate. For novel, un-hashed material,
`classify_novel_csam` (`:1894`) is a Thorn-Safer-class signal scorer whose
`run_novel_csam_classifier_eval` (`:1971`) holds it to a precision/recall bar.
The honest caveat: with `sha2` as the only hashing primitive, the perceptual
hashes are deterministic stand-ins for the licensed algorithms, and the novel
classifier scores labeled markers — the _pipeline_ is real and gated; the
licensed model and database feed are the seam.

### Grooming and longitudinal endangerment

`classify_grooming_conversation` (`:2022`) is a Project-Artemis-class scorer
that weights real grooming signals — secrecy pressure ("our secret"),
off-platform migration ("switch apps"), isolation/meet-up pressure,
gift/currency leverage, boundary-testing requests, and repeated adult-to-minor
contact — and routes any conversation scoring at or above the threshold to the
`kuanyin-human-review` queue (`:2138`). Voice, the monolith's highest-risk
grooming channel, is screened at the gateway: `MawuVoiceSafetyPolicy`
(`mawu-gateway/src/lib.rs:648`) evaluates a platform voice-safety tap and yields
`RoutedToReview` (`:800`) rather than trusting a transcript alone. Above single
conversations, `run_sentinel_child_endangerment_eval` (`:3283`) is the
Sentinel-class longitudinal detector: its test surfaces a seeded **cross-realm**
endangerment pattern to review, catching the realm-hopping predator that any
per-realm view would miss — the same signal a Tech-Coalition **Lantern** join
(below) shares across platforms.

### Age assurance and minor protection

`evaluate_facial_age_estimate` (`:3075`) treats the third-party age vendor as an
injected estimate and enforces the **privacy-minimization invariants** in code:
the platform must never see the raw biometric (`platform_raw_biometric_seen`),
the vendor must not retain it (`vendor_retained_biometric`), the biometric must
be deleted within `AGE_ASSURANCE_BIOMETRIC_DELETION_SLA_MS = 60_000` (60 s,
`:85`), liveness and consent must be attested, and confidence must clear
`AGE_ASSURANCE_MIN_CONFIDENCE_BASIS_POINTS = 7_500` (`:86`) — any failure forces
the safest band, `Everyone`. Accepted users are bucketed into `SekhmetAgeBand`
(`:1044`) by `age_band_for_estimated_age` (`:3983`).
`evaluate_minor_protection_request` (`:3142`) then applies the day-one OSA/DSA
posture: **cross-age contact and unfiltered chat are restricted by default**
whenever a minor is on either side, and age-gated features demand a sufficient
band. `run_minor_protection_eval` (`:3204`) — the `minor-protection` gate — only
passes when every user is age-banded, every biometric deletion completed, the
default cross-age and unfiltered-chat restrictions all fired, and there were
**zero** false-allows.

### NCII, the moderation pipeline, and contextual reports

NCII follows the TAKE IT DOWN Act shape: `ingest_stopncii_hashes` (`:2798`)
takes **StopNCII** hashes, `evaluate_ncii_asset_ingest` (`:2836`) blocks
matching uploads, and `run_ncii_takedown_pipeline` (`:2864`) drives reported
items to removal within `NCII_TAKEDOWN_SLA_MS = 48 h` (`:84`), with
`share_lantern_signal` (`:2950`) emitting the cross-platform signal. The general
moderation path is three layers: `pre_screen_moderation_content` (`:2194`) does
an ML pre-screen, `evaluate_sekhmet_moderation_pipeline` (`:2300`) escalates to
Kuanyin human review, and a contested removal opens a **Themis DSA appeal**
bounded by `SEKHMET_DSA_APPEAL_SLA_MS = 72 h` (`:88`) — the test
`moderation_safety_eval_runs_three_layers_and_dsa_themis_appeal_within_sla`
proves the full machine-then-human-then-appeal flow stays in SLA. Reports of
in-world conduct are not taken on faith:
`evaluate_sekhmet_contextual_report_flow` (`:2641`) requires both telemetry
**and** a replay-clip as evidence before a report is actionable.

## Anti-cheat and client integrity

Anti-cheat in a creator republic has a structural problem FiveM never solved:
the operator owns the node. V7's answer is that the _detection_ never trusts
that node's client, and _enforcement_ against the platform routes platform-side.

### The structural floor: server-authoritative netcode

A tampered client cannot grant itself state because the realm protocol treats
every cross-trust message as hostile. `RealmEnvelope::validate_cross_trust`
(`realm-protocol/src/lib.rs:1781`) checks sender, detached signature, security-
token MAC, and an HMAC-SHA256 over the payload _before_
`apply_client_intent_to_authoritative_state` (`:1835`) will mutate anything, and
only then if the intent carries the right scope. Two tests pin the property that
matters: `rejects_forged_payload_even_with_valid_token` (`:3788`) and
`rejects_forged_security_token_even_when_envelope_is_resigned` (`:3799`) — a
tampered intent is dropped even when the attacker re-signs the envelope, and
`run_event_tamper_eval` (`:2624`) proves a whole corpus of forged/unsigned/
mis-scoped events causes zero authoritative mutation. The `V7IdentityFirewall`
(`substrate-bridge/src/lib.rs:325`) ensures realm code only ever sees an opaque
per-realm handle, so a cheat can't even address a platform account.

### Native detectors that extend the V5 stack

On that floor, `moremi-realm-server` ships the V5 anti-cheat stack natively for
community realms. `MoremiAntiCheatSignalKind` (`:3205`) enumerates seven server-
observed signals — EAC heartbeat, aim plausibility, aim snap, wall-history,
speed-delta, auto-fire, and an ML classifier — and the detectors are real
physics, not placeholders: `moremi_anticheat_impossible_turn_rate` (`:12027`)
computes `angle / tick` against a 720°/s ceiling, `moremi_anticheat_speed_delta`
(`:12059`) compares a distance/time ratio to max speed, and
`moremi_anticheat_auto_fire` (`:12078`) flags impossibly tight, repeated shot
intervals. `evaluate_moremi_anti_cheat_signal` (`:11643`) is the verdict engine,
and its first act is decisive: a signal **not observed on the authoritative node
is ignored** (`:11650`), so a tampered client can neither forge a strike against
a rival nor suppress one against itself (`client_suppression_ignored`,
`:11741`). Risk rolls into a `Clean → Watch → Strike → BanReview` verdict; on
the third realm-scoped strike (`MOREMI_ANTI_CHEAT_THREE_STRIKE_LIMIT`, `:11729`)
it issues a **realm-scoped** ban and routes a **platform** ban-review with a
companion appeal — never an automatic global ban from one realm.
`run_moremi_anticheat_eval` (`:11776`) holds precision and recall to a bar; it
is the `anticheat` CI gate.

Client integrity itself is platform-owned: a hardened, signed, attested client
on the Roblox-Hyperion precedent that operators never patch, with EAC
kernel/userland attestation surfaced as the `EacHeartbeat` signal. The ML side
composes the shared plane's review-only governance: `@nous/safety`'s anti-cheat
model card requires human review and forbids automated discipline, the posture
detailed in the V2 backbone — Sekhmet's verdict engine produces _evidence and
routing_, a human issues platform discipline.

### In-realm moderation vs. the platform floor

Realm operators get their own moderation tools without ever touching the
platform floor. `moremi_nana_moderation_admin_actions` (`:6811`) models a realm
moderator's spectate / freeze / teleport / kick / realm-ban actions, each
written to a tamper-evident audit log; only `RealmBan` carries
`platform_policy_signal: true`, escalating to the platform-safety floor. An
operator can run their realm's conduct rules; they cannot opt out of CSAM
scanning, age assurance, or a cross-realm ban.

```mermaid
flowchart TD
  UP[Creator upload] --> MAL["scan_artifact + malware-corpus<br/>:3461 · :3491"]
  MAL -->|verdict ≠ clean| BLOCK[[blocked: not served]]
  MAL -->|clean| CSAM["scan_csam_hash_ingest<br/>PhotoDNA/PDQ/CSAI/Rendered-2D :1806"]
  CSAM -->|hash match| NCMEC[[blocked before serve<br/>+ NCMEC/incident path]]
  CSAM -->|no match| NCII["NCII: StopNCII match<br/>≤48h takedown :2864"]
  NCII --> SUPPLY["content-address + HMAC sign<br/>+ step-up on republish :1452"]
  SUPPLY --> GATE["evaluate_distribution_gate<br/>clean scan ⇒ fetchable :3536"]
  GATE --> SERVE[(served to clients<br/>via Ixchel lock)]

  subgraph runtime["live realm (authoritative node)"]
    VAL["validate_cross_trust<br/>HMAC-SHA256 :1781"] --> AC["anti-cheat detectors<br/>turn/speed/snap/auto-fire :12027+"]
    AC --> VERD["verdict: Clean→Watch→Strike→BanReview<br/>3-strike, authoritative-only :11643"]
    CHAT[chat / voice] --> GROOM["grooming + voice-safety tap<br/>:2022 · gateway:648"]
  end
  GROOM --> KY["kuanyin-human-review queue :2138"]
  VERD -->|3rd strike| RB["realm-scoped ban<br/>+ platform ban-review :11729"]
  KY --> THEMIS["Themis DSA appeal ≤72h :2300"]
  SENT["Sentinel cross-realm + Lantern<br/>:3283 · :2950"] --> KY
```

## Where this connects

- **Sideways:**
  [Ixchel: Modding Runtime & WASM Sandbox](./ixchel-modding-runtime-and-wasm-sandbox.md)
  — the capability sandbox and content store that contain _executable_ UGC, the
  abuse surface Sekhmet's ingest gate stands in front of;
  [Eunomia: Governance & the Ori Bridge](./eunomia-governance-and-ori-bridge.md)
  — where platform bans, appeals, and the five-tier rule space meet the
  non-negotiable safety floor; and
  [Abundantia: Economy Firewall & Anti-Fraud](./abundantia-economy-firewall-and-anti-fraud.md)
  — the payout-fraud and RMT defenses that share Sekhmet's account-graph
  posture.
- **The boundary it enforces:**
  [Architectural Thesis, Trust Boundary & Topology](./thesis-trust-boundary-and-topology.md)
  — why a realm is assumed hostile and which concerns are never delegated.
- **Platform foundations it composes:**
  [Auth & Identity](../../platform/auth-identity.html) (the account root age
  assurance and bans resolve against), and the shared Aphrodite / Kuanyin /
  Themis trust-safety plane (`libs/aphrodite/age-verification`,
  `apps/lilith/svc-ai/src/csam-protection`, `libs/kuanyin/community-harmony`,
  `libs/themis/privacy`) whose seams the native Rust scanner names.
- **Real code cited here:** `apps/v7/sekhmet-scanner/src/lib.rs`,
  `apps/v7/moremi-realm-server/src/lib.rs`, `apps/v7/mawu-gateway/src/lib.rs`,
  `libs/v7/realm-protocol/src/lib.rs`, `libs/v7/substrate-bridge/src/lib.rs`,
  and `scripts/v7/verify-adversarial-eval-gates.mjs`.
- The orientation hub: [../V7_ARCHITECTURE.md](../V7_ARCHITECTURE.md).
