> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plurai.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Data and privacy

> What leaves your machine, how uploads are packaged, disclosed and audited, and what local anonymization changes.

This page explains what data the plugin sends to the Plurai backend, the controls you have over it, and where to find the authoritative record of every upload.

## Your terms are the primary control

Everything you upload, anonymized or raw, is handled under the Terms of Service and the Privacy Policy you accepted at sign-up. Those terms, not a local scrub, govern how your data is processed.

Local anonymization is optional, extra protection on top of those terms. It is not the only control.

## What leaves your machine

Your data leaves your machine only through the SDK's upload commands, which run locally:

| Command | Uploads | Started by |
| - | - | - |
| `plurai ingest-corpus` | Knowledge base content | `/build-rag-corpus`, `/simulation-generate-suite` |
| `plurai ingest-traces` | Production traces | `/analyze-traces` |
| `plurai ingest-doc-examples` | Example documents | `/upload-doc-examples` |
| `plurai ingest-bundle` | Scenario bundles of real records or conversations | `/upload-scenario-bundle`, `/trace-to-scenarios` |
| `plurai ingest-run`, `plurai ingest-run-report` | Run results | `/simulation-run`, `/simulation-generate-suite`, `/analyze-simulation` |
| `plurai ingest-descriptions` | `plurai.config.yaml`, `simulation_prd.md`, `scenario_variables.yaml`, the scan's contract | `/simulation-scan-agent`, `/build-rag-corpus` |

The SDK reads your data sources with your credentials on your machine. Those credentials (your observability platform key, your database connection) never leave it. The plugin itself never scrubs or uploads bytes; the SDK owns the upload end to end.

While a simulation runs, each conversation is also sent to the Plurai backend so it can play the simulated user and score the result: the user's messages, your agent's replies, its tool calls and what they returned.

**No telemetry.** Neither the plugin nor the SDK sends anything about how you use them. Support sees only what you choose to paste, such as the output of `plurai diagnose`. Two things stay local or are minimal: once a day the plugin checks GitHub's public tag list for a newer release, sending nothing about you or your project (turn it off with `PLURAI_NO_UPDATE_NOTICE=1`), and install failures are logged locally in `~/.plurai/support_refs.jsonl`, which is never sent (turn it off with `PLURAI_NO_SUPPORT_REFS=1`).

> [!NOTE]
>
> The agent descriptions (`plurai.config.yaml`, `simulation_prd.md`, `scenario_variables.yaml`) are sent as written, in both postures. They describe your agent's code and tools; anonymization does not scrub them. The same holds for a knowledge base's domain description.

## Anonymization posture

Each Environment declares its anonymization posture once, with the top-level [`anonymize`](https://docs.plurai.ai/reference/config#anonymize) key in `plurai.config.yaml`. `/simulate` asks at the start. When you run stages yourself, the first command that uploads data asks. Either way, your answer is written there.

> [tab] Raw (default)
>
> `anonymize: false`, or the key absent.
>
> Data is uploaded as-is. Every upload prints a `RAW (anonymization off)` banner, so you always know. The upload is governed by the Terms of Service and the Privacy Policy.

> [tab] Anonymized
>
> `anonymize: true`
>
> Every upload scrubs personal data on your machine before anything leaves. Personal data is replaced with a one-way keyed hash. The key is generated per workspace in `.plurai/anon.key`, which is never committed.
>
> The scrub is **fail-closed**. It refuses to run, and uploads nothing, unless these are installed:
>
> * the `plurai[anonymize]` extra, and
> * a spaCy English model (`en_core_web_lg`, `en_core_web_md` or `en_core_web_sm`).
>
> To anonymize images and PDFs, also install the `plurai[anonymize-binary]` extra, which needs Tesseract and Poppler.

> [!WARNING]
>
> **An Environment cannot mix postures.** After an Environment has uploaded under one posture, an upload under the other is refused. Mixing raw and pseudonymized data would silently break the links between your records. To change posture, start a new Environment.

Some commands work only on raw data for now. `/trace-to-scenarios` refuses to run under the anonymized posture.

## How an upload is packaged

Every upload follows the same steps:

**1. Build one archive**

The SDK bundles the data into a compressed archive. The archive is deterministic: the same input always gives the same bytes and the same checksum.

**2. Disclose**

Before any request that carries content, the SDK prints a disclosure preview to the terminal: what is being sent, its size, its checksum, the posture, and under anonymization a scrub summary. It also writes it to `.plurai/uploads/disclosure-<kind>.txt`.

**3. Record**

It appends an entry to `.plurai/uploads/audit.log`.

**4. Upload**

It sends the archive. If the backend already holds identical bytes, nothing is sent. If the bytes change after the disclosure, the upload aborts.

The SDK prints a manifest for the upload: its checksum, its size, its posture and the fingerprint of the anonymization key. The backend uses it to fetch exactly those bytes.

An upload larger than the backend's size limit never leaves your machine. The SDK checks the size first and names the largest files so you can narrow the export.

## The audit log

`<your-project>/.plurai/uploads/audit.log` is the authoritative record of what left your machine and under which posture, for both postures. When you need to answer "what exactly did Plurai receive?", read this file.

`.plurai/` holds runtime state: the audit log, upload previews, and the anonymization key. Add `.plurai/` to your project's `.gitignore` so none of it is committed.

## Your consent

* **Uploads.** Each upload is a shell command. In your coding agent's default permission mode you approve each one. Under `/simulate` or auto mode they run without a prompt, but the SDK still prints a disclosure first and logs every upload in `.plurai/uploads/audit.log`. See [Permissions](https://docs.plurai.ai/reference/permissions.md).
* **Harness edits.** When the suite's quality loop finds a fix for `simulate.py` (or the runner declared in `harness.entry_wrapper`), it asks you first. For runs where nobody can answer, such as CI, set [`approve_harness_edits: true`](https://docs.plurai.ai/reference/config#approve_harness_edits) to approve those fixes in advance. Leave it out to keep them unapplied and reported. The plugin never writes this key for you.
* **Your agent's code.** No command edits your agent's source. `/simulation-fixes` proposes fixes; you apply them.

## What the Report withholds under anonymization

On Claude Code, the Report is published as a private Artifact page. On Copilot CLI and Codex CLI, it is a local file you open in your browser.

Under `anonymize: true`, no customer text ships in the Report. It keeps structure, ids, counts, verdicts and eval names, and marks each withheld value as `[withheld]`:

* Conversation turns, and every quote a judge or a finding took from them.
* Judges' reasoning and the explanation of each finding.
* The seeded agent context, and the text the Suite wrote for each Scenario: its summary, pass criteria, starting data and the Persona's background, style and sample dialogue. A Persona keeps only its name.
* The seeded and final world state, which keep only the kind of each record.
* Every tool call's arguments and responses.
* Evidence, quotes and excerpts in findings, eval descriptions and provenance quotes.
* Knowledge base text: each chunk keeps only its document name and index.

In both postures, tool-call values in the Report are hardened: keys that look like credentials are withheld, and URLs, hosts, email addresses and IP addresses are replaced.

## Your login

When you sign in with your browser, the SDK creates its own key and saves it privately on your machine (`~/.plurai/credentials.json`, readable only by you). The key is never shown, typed or copied into chat. It goes only to the Plurai backend it was issued for, and the plugin hands it only to the installed SDK. `plurai logout` revokes it. See [Environment variables](https://docs.plurai.ai/reference/environment-variables.md).

## Next steps

> [card] [Environment variables](https://docs.plurai.ai/reference/environment-variables.md)
>
> Connect to the backend and set the sandbox.

> [card] [Configuration](https://docs.plurai.ai/reference/config.md)
>
> Set `anonymize` and `approve_harness_edits`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.