Metadata-Version: 2.5
Name: maskflow-evidence
Version: 0.1.0
Summary: MaskFlow evidence layer: a metadata-only, verifiable record of what was masked -- never the values. Self-hosted emitters (stdout, file, syslog, webhook, OTLP), off by default.
License: MIT
Requires-Python: >=3.10
Requires-Dist: maskflow-core<0.8,>=0.7.0
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: otlp
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.25; extra == 'otlp'
Requires-Dist: opentelemetry-sdk>=1.25; extra == 'otlp'
Provides-Extra: webhook
Requires-Dist: httpx>=0.27; extra == 'webhook'
Description-Content-Type: text/markdown

# maskflow-evidence

A **metadata-only, verifiable record of what MaskFlow masked** — never the
values themselves. Publishing the schema and shipping the emitters in the
open lets any user confirm, by reading the code, exactly what leaves their
environment.

> Part of [MaskFlow](https://github.com/maskflow/maskflow). MIT, free
> forever, no telemetry.

## What an event looks like

```json
{"event_id":"…","ts":"2026-09-07T12:00:00Z","session_id":"…","service":"support-bot",
 "environment":"prod","entity_type":"AADHAAR","count":1,"score":0.98,
 "recognizer":"pattern:AADHAAR","action":"masked","provider":"openai","model":"gpt-4o",
 "pack_version":"0.5.0","engine_version":"0.6.0"}
```

There is **no field that can carry free text.** Every string is a bounded
slug; there is no place for a detected value, a placeholder, or the mapping
between them. This is enforced structurally in `schema.py` and in CI by
`tests/test_schema_metadata_only.py`.

## Off by default

Nothing is emitted unless you turn it on. In `.maskflowrc`:

```toml
[evidence]
enabled     = true
sink        = "file"          # stdout | file | syslog | webhook | otlp
path        = "evidence.log"
service     = "support-bot"
environment = "prod"
```

The gateway reads `MASKFLOW_GATEWAY_EVIDENCE_*` environment variables with
the same names.

## Sinks

| sink | transport | extra |
|---|---|---|
| `stdout` | one JSON line per event | — |
| `file` | size-rotated JSON lines | — |
| `syslog` | `SysLogHandler` | — |
| `webhook` | `POST` JSON per event | `maskflow-evidence[webhook]` |
| `otlp` | OpenTelemetry log records | `maskflow-evidence[otlp]` |

## What is deliberately **not** collected

Raw values, masked values, the mapping, request/response bodies, prompt
text, and any user identifier beyond a caller-supplied opaque `session_id`.
See `docs/evidence.md` for the full statement.
