PII matrix
Route:
/pii on the dashboard. Backed by: GET /api/entities/pii-matrix.
credential, payment_card, government_id) are floor-locked to block and pinned to the top, regardless of policy. Select any row to open its entity’s drilldown — columns, metrics, and joins — below the grid.
This is the surface to open before you trust an agent against a new schema. It answers, at a glance:
- Does my
usersentity have apayment_cardcolumn hiding inside? - Which entities will trip the default
--pii-blockpolicy onschemabrain serve? - Did the heuristic classifier mis-tag anything I should review?
What the matrix shows
Each row is one classified column and carries:| Field | Meaning |
|---|---|
entity | The semantic entity the column belongs to (e.g. user, payment_method). |
qualified_table · column | The bound physical schema.table and column name (e.g. public.users · password_hash). |
| category cells | One cell per PII category; lit when the classifier tagged the column with that category. |
band | The column’s single advisory confidence band (ADR 0009) — drives the cell shading. A classified column with no band renders —, never a faked 0. |
status | The classification-derived disposition: block (catastrophic floor), redact (other pii / confidential), or allow (public / internal). |
The
status here is the default disposition from classification, not the operator’s live enforcement. The editable block / redact / allow grid lives on Policy; a non-floor redact understates only if the operator has additionally blocked that category there. The catastrophic floor is the one disposition the matrix asserts as a hard guarantee.How the tags get there
The cell tags come from the heuristic PII classifier that runs duringschemabrain index. The classifier is local — no LLM call, no network — and inspects column names, declared types, and a small set of well-known patterns (email, ssn, card_number, etc.).
If you ran schemabrain index --no-pii-classify, every column renders unclassified — no lit category cells, no band, status allow — the audit row’s pii_categories column is also empty in that mode, and --pii-block enforcement on serve has nothing to act on.
How this connects to refusals
The same tags that populate the matrix drive refusal behaviour atschemabrain serve:
- The
--pii-blockflag onservetakes a comma-separated category list. - When omitted, it defaults to
credential,payment_card,government_id— the catastrophic-leak set. - If a compiled
get_metricplan touches a blocked category, the call returns arefusedenvelope (refusal_reason='pii_blocked') and appears as a row on the Refusals surface.
--pii-block contact,health,...) or to revise the schema before exposing it to an agent.
When to refresh
The matrix is computed from the SQLite store, which is updated byschemabrain index. Re-runs:
- Are idempotent — unchanged tables stay tagged.
- Re-tag changed columns selectively.
- Cost zero LLM dollars (the classifier is heuristic).
Related
PII taxonomy
The 12 categories the classifier emits, with sensitivity tiers.
Refusals surface
Where a blocked tag becomes a refused envelope.
schemabrain index
The command that populates these tags.
schemabrain serve --pii-block
The runtime policy that consumes them.