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

# PII gate: detect personal information in output

> Scan every string in agent output for email addresses, Social Security Number patterns, and US phone numbers before the response leaves your system.

The PII gate walks every string value in `ctx.output` — recursively through nested objects and arrays — and fails the evaluation the moment it finds a pattern that looks like personal identifying information. It is intended as a last-resort guardrail: a lightweight regex-based check that catches accidental data leakage before an agent's response reaches end users or gets logged.

All three checks run by default. You can disable any of them individually when your domain requires it — for example, a healthcare support bot where phone numbers are expected in output.

## Usage

```typescript theme={null}
import { createEngine, gates } from "@pecta/core";

const engine = createEngine({
  gates: [
    gates.pii(),
  ],
});

const result = await engine.evaluate({
  agent_id: "support-bot",
  tool: "lookup.customer",
  output: {
    message: "I found your account. Contact us at jane.doe@example.com or 555-867-5309.",
  },
});
// result.passed === false
```

## What it detects

### Email addresses

Matches standard email formats using the pattern:

```
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
```

Examples flagged: `user@example.com`, `first.last+tag@company.co.uk`

### Social Security Numbers

Matches the `NNN-NN-NNNN` format while excluding known invalid ranges (group `000`, `666`, any 900–999 area number, group `00`, serial `0000`):

```
\b(?!000|666|9\d{2})\d{3}-(?!00)\d{2}-(?!0000)\d{4}\b
```

Examples flagged: `123-45-6789`\
Not flagged: `000-12-3456`, `666-00-1234` (structurally invalid SSNs)

### US phone numbers

Matches common North American phone number formats with optional country code, parentheses, and a variety of separators:

```
\b(?:\+?1[-.\s]?)?\(?[2-9]\d{2}\)?[-.\s]\d{3}[-.\s]\d{4}\b
```

Examples flagged: `(555) 867-5309`, `+1-800-555-0100`, `555.867.5309`

## What a failure looks like

```json theme={null}
{
  "name": "pii",
  "passed": false,
  "reason": "email address detected in output",
  "latency_ms": 0.22
}
```

```json theme={null}
{
  "name": "pii",
  "passed": false,
  "reason": "SSN-shaped string detected in output",
  "latency_ms": 0.18
}
```

```json theme={null}
{
  "name": "pii",
  "passed": false,
  "reason": "phone-shaped string detected in output",
  "latency_ms": 0.16
}
```

## Configuration

<ParamField path="email" type="boolean">
  Enable email address detection. Defaults to `true`.
</ParamField>

<ParamField path="ssn" type="boolean">
  Enable Social Security Number detection. Defaults to `true`.
</ParamField>

<ParamField path="phone" type="boolean">
  Enable US phone number detection. Defaults to `true`.
</ParamField>

<ParamField path="name" type="string">
  Override the gate name recorded in results. Defaults to `"pii"`.
</ParamField>

## Disabling individual checks

```typescript theme={null}
import { createEngine, gates } from "@pecta/core";

const engine = createEngine({
  gates: [
    gates.pii({
      email: true,
      ssn: true,
      phone: false, // phone numbers are expected in this context
    }),
  ],
});
```

<Note>
  The PII gate uses regex patterns and will produce both false positives and false negatives. It is a best-effort guardrail, not a comprehensive PII scanner. Strings that look like SSNs or phone numbers but are not real personal data will still fail the gate.
</Note>

<Warning>
  Like the filesystem gate, the PII gate scans output recursively and caps traversal at 10,000 nodes. Very large nested outputs beyond that cap are not fully scanned.
</Warning>
