AI data sharing
Per-feature control over what tenant data each AI feature may send to the model — cleartext, redacted, aggregates, or disabled.
AI data sharing
Every AI feature in Pact sends some of your data to the model provider. Some send only categories (a role plus an industry); others send free-text notes that may contain names, emails, and phone numbers. Data sharing is the single switch that decides, per feature, how much of that data leaves the process — and it is enforced before the prompt is built, not after.
The control lives at Admin → AI → Data sharing and is backed by
core.ai.data_sharing, read by core.ai.client.AIClient via resolve_mode(...)
on every call.
Enforced at call time
The AI client resolves the effective mode for every
(tenant, feature) pair on each call and applies the matching
redaction before the prompt leaves the process. disabled
short-circuits the model call entirely and the feature falls back to its
heuristic.
The four modes
RedactionMode — pick one per feature (or set a tenant-wide default):
cleartext— send as-is. Requires an explicit per-feature opt-in.redacted— strip emails, phones, cards, addresses, and secrets before sending. This is the default (DEFAULT_MODE), the safest sane posture.aggregates— redact and treat any remaining free-text as non-grounding.disabled— never call the model; use the feature's heuristic fallback.
How the effective mode resolves
Precedence, highest wins:
per-feature override → tenant default → global default (redacted)
A missing row means "inherit", so a fresh tenant with no configuration lands on
redacted for every feature — no backfill migration required. Settings are
keyed by (tenant_id, feature) in ai_data_sharing_settings
(alembic 0182_ai_data_sharing_settings); the sentinel feature __default__
stores the tenant-wide default.
The feature registry
FEATURE_REGISTRY is the source-of-truth inventory of every AI feature: which
fields each one sends to the provider and how sensitive that data is. It drives
the admin table so you can see, feature by feature, exactly what would be shared
before you choose a mode.
API
Admin/owner only, tenant-scoped:
GET /v1/admin/ai/data-sharing/features # inventory + effective mode per feature
PATCH /v1/admin/ai/data-sharing/features/{feature} # set a feature's mode (writes an audit event)
POST /v1/admin/ai/data-sharing/features/{feature}/test # preview the redaction on a sample
GET /v1/admin/ai/data-sharing/log # what was actually shared, per call
GET /v1/admin/ai/data-sharing/log/csv # export the share log
GET /v1/admin/ai/data-sharing/field-classes # sensitivity classes for each field
First-send notice
The first time a feature actually sends data, Pact fires a one-time
"AI is now active — here's what it shares" notice (mark_first_send /
unacknowledged_notices), surfaced as an in-app banner and an admin email, with
an acknowledgement endpoint (/notices/ack). Every share is recorded to the
data-share log (ai_data_share_log, alembic 0218_ai_data_share_log) so you can
audit exactly what left the tenant.