The map is a searchable catalog of your data’s structure — datasets, columns, owners,
lineage, and which columns look like personal data. Reading it well means knowing what Regixo actually
measured, how much to trust each flag, and where the honest gaps are.
Two things to know before you read itThe counter reads datasets · columns. A dataset is a whole table; a personal-data column is
one flagged field inside it — so “7 datasets hold personal data · 12 columns” would mean twelve flagged
fields spread across seven tables. The datasets are where personal data lives; the columns are
what the classifier flagged. And two labels carry stricter rules:Art. 9 is
special-category data — health, beliefs, biometrics; Art. 10 is criminal-offence data. Each has
its own count and its own filter.
Your whole job on this page, in order
Reading the map well is a fixed order — counts first, then the flags, then source by source, then decide.
In order:
Open it — regixo open lands on the Map at localhost:4319. (how ↓)
Read the counts first — datasets · personal-data columns, and the separate Art. 9 / Art. 10 counts. (how ↓)
Check the flagged columns — open a dataset and read each flag and the rule that matched it. (how ↓)
Look per source — open each source fold; confirm the sources you expect are all there. (how ↓)
Decide what needs correcting — note every flag that looks wrong for the next page. (the trust decision ↓)
Reading is all this page asks of you — you change nothing here. Fixing a wrong flag is the next page.
Read one dataset all the way through (the worked example)
Before the detail, read one dataset end to end so the order is concrete. Here is
app-db / customers through all five steps:
Step
On app-db / customers
What you read, and decide
1 · Open
regixo open → the Map at localhost:4319.
The workbench opens on one line of plain English; nothing is picked yet.
2 · Counts
The toolbar reads 63 datasets · 170 personal-data columns.
Read this first — it sizes the estate. Note the separate Art. 9 and Art. 10 counts; “0 Art. 9” is a claim to sanity-check, not a proof.
3 · Flags
Open customers: email, name, date_of_birth flagged by field name; created_at reads not personal.
Each flag shows the rule that matched. The three look right; created_at correctly isn’t personal.
4 · Source
The app-db fold counts its datasets and personal columns; every source you connected has its own fold.
Confirm every source you expect is present — a fold missing means a source didn’t scan.
5 · Decide
A bland notes column reads not personal, but you know it can hold free-text health notes.
The classifier can’t see values, so it missed it. Note it to correct on the next page — don’t fix it here.
Step 1 · Open the map
Open the searchable map in your browser. Run this one yourself — it holds the terminal open:
run
$ regixo open
✋Run this one yourself, not through your agent — it keeps running until you press Ctrl+C, so give it a terminal of its own.
Opens the map in your browser at localhost:4319. From the terminal you can search it
too:
say
“Search my Regixo catalog for columns that look like email addresses.”
Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo search email
Three ways to reach the same map — pick whichever fits the moment:
▤ In the portal
regixo open lands on the Map. Search from the box
("Search datasets & columns…") or narrow the rail with the filters — Source,
Personal data, Art. 9, Art. 10, Undescribed, each carrying a live
count. Open a dataset and the pane holds every action: Correct a column's flag,
Save or Draft a description, and Assert a flow into or out of it. A tour:
the free portal tour.
⌨ Say it, or run it
Both actions are at the top of this page: regixo open and
regixo search. Say the sentence to the coding agent already open in your project, or
run the command yourself — it is the same command in the same shell, either way.
✦ A connected assistant
A different surface. Register the read-only regixo mcp server once, and an
assistant answers "where is X · what's personal · what feeds this table" by chaining
search_datasets → get_dataset → get_lineage. It reads; it
never changes the map. See Use an AI agent.
Steps 2–4 · Read the map — counts, then columns, then sources
Read the counts first. The toolbar across the top carries the title, the two headline counts
(datasets · personal-data columns) and a ↻ Refresh now button ("re-scan · stays local").
The counts size the whole job before you open anything; the two extra labels — Art. 9 and
Art. 10 — each carry their own count in the filters. The Map is a workbench that fits on
one screen. The rail on the left
holds the search box, the filters, and one collapsible fold per source — each fold counting its
datasets and its personal-data columns, and grouping the tables it flagged as holding personal data
above the ones it didn't. The rail and the pane scroll independently. Below is the real thing — the
toolbar, and the rail with the stripe fold opened. (The five filters sit above the folds;
they are shown, with their live counts, on Classify &
correct.)
what you’ll see — the Map workbench: the toolbar, the rail with one of your ten source folds open, and the line the pane opens with
This is every place your business stores data — Regixo read the labels, never the values. Pick a dataset to see what it holds. Anything marked ● personal feeds your compliance record →
Before you pick anything, the pane opens with that one line of plain English — and, under it, the
trust panel (Reached · Fresh · Confirmed · Sealed — the same verdict an AI assistant gets
from get_provenance; the Reached card is where coverage lives — "All 10 sources")
and a card per source (datasets · personal · sensitive · when it was last scanned).
Open a dataset and the pane answers four questions in order: what it is (source, driver,
when it was scanned, row estimate, who owns it in the database, and a plain-words summary), what it
holds (every column, its type, its personal-data flag — and the small grey note saying how
Regixo recognised it), what it's for (the description), and where the data flows. Every
flag carries a Correct control, and a labels legend explains the colour codes without a
hover. Below is the top of that pane — what it is, and what it holds. The description box and
the lineage river sit under it, and are shown on
Enrich & share.
what you’ll see — the Map, with a dataset open: the top of the pane on app-db / app / customers — what it is, and its columns
In plain words: this dataset holds 5 kinds of personal data — date of birth, email, name, national id, and phone. That’s why it feeds your compliance record →
Columns
What do the labels mean?the label key
● personalLooks like personal data — a name, email, and so on.
⚠ Art. 9Looks like special-category data — the extra-sensitive kinds, such as health or beliefs. Stricter legal rules apply.
⚠ Art. 10Looks like criminal-offence data (convictions, offences). Allowed only under official authority or where the law authorises it.
? unknownA container column (json, blob) Regixo can’t see into. Confirm yourself whether it holds personal data.
The small grey note (e.g. “by field name”) says how Regixo recognised it. Regixo reads column names and types only — never the values — so double-check anything that looks wrong.
Column
Type
Personal data
created_at
timestamp with time zone optional
not personalCorrect
date_of_birth
date optional
● Date of birthby field nameCorrect
email
text required
● Emailby field nameCorrect
Regixo read the column names and types — never the values. The small grey note beside a flag says how it was spotted; row count is an estimate from the database’s own statistics.
What the scanner reads — and refuses
Regixo reads metadata only. It never runs SELECT *, never counts rows, and
never reads a value out of a table. Concretely, per dataset it collects:
Collected
From
Notes
Tables, columns, data types, nullability
information_schema
All SQL databases. VIEWs are catalogued as datasets too.
Row-count estimates + owning DB role
pg_class.reltuples
Postgres/Redshift only. The planner’s estimate — shown as ~N rows (estimate), never a COUNT(*). Never ANALYZEd → shown as unknown, never a fake 0.
Automatic lineage (view → table)
pg_depend / pg_rewrite
Postgres/Redshift only. Relation names, never SQL-text parsing.
Personal-data flags
column names + types
The classifier runs on names and declared types — never values.
The hard line
Raw data never leaves your machine (Hard Rule #2). If Regixo ever sampled a value to check a
classification, it would do so in memory and discard it — no sampling connector is even built today.
MySQL and SQL Server give tables, columns and types, but no auto row-estimates
or auto lineage (those come from Postgres catalog tables). That’s a limit, stated honestly on the map.
How a column gets flagged
Every personal-data flag comes with the rule that matched — the small grey note beside the
flag saying how Regixo recognised the column — so you can judge it. Regixo evaluates rules
in order and takes the highest-confidence hit; a column is “personal data” when the best confidence is
≥ 0.6. That score is deliberately not shown beside the flag.
Tier
Confidence
What it catches
Deny-list
1.0 (hard-stop)
Special category (Art. 9) and criminal-offence (Art. 10) terms — e.g. health_status, diagnosis, =race, conviction_date.
Name rule
0.9
The common kinds by column name — email, phone, name, address, national_id, financial, ip, …
Regex
0.7
Backstop patterns for email / phone / ssn·nino·tax_id.
Your patterns
0.7
Anything you add in regixo.ymlpii.extraPatterns.
Type rule
0
Opaque json/jsonb/blob/bytea → “contents unknown (needs you)”. Never personal by itself.
Why trace_id isn’t flagged as “race”
Matching is whole-token, never substring. Regixo splits a name on camelCase and any
non-letter (trace_id → trace, id), so the deny-list term
=race (which means “the entire name is exactly race”) can’t match
trace. That precision is why the classifier has zero false Art. 9 flags on the
infrastructure benchmark set.
Step 5 · Decide what needs correcting — how far to trust a flag
A flag is the classifier’s best guess from the column’s name and type — never from a value it
read. So for anything that looks off, ask two questions, and act on the first yes:
Ask…
If yes →
1. Is this a false flag? A suggestive name on a column that doesn’t hold that data — a server_ip that is infrastructure, not a person; a country that is just a country.
Note it to clear on the next page (correct to not personal).
2. Is a real one missing? A bland name on a column that does — a status or notes that actually holds a health state.
Note it to add yourself — the machine will not prompt you for what it could not see.
Anything you’re unsure of, check the rule the flag cites (the small grey note) and, if
you can, the column’s real contents. You correct both kinds the same way on the next page — this step is
only deciding which flags to touch.
How far to trust a flag
The classifier reads names and types only — it never sees a value. So two things happen: a
blandly-named column (a status that actually holds a health state) can hide personal
data, and a suggestive one can false-flag. Every flag is a guess, labelled as a guess, that you
override on the next page.
That is also why “0 Art. 9” is a claim to sanity-check, not a proof. It means the classifier
matched no special-category term by name — nothing more. If your business handles health, beliefs or
biometrics, look at the tables that would hold them before your compliance team leans on that zero.
Languages
The classifier ships term packs for many languages. Recall is benchmarked and passing for
English, German, French and Dutch (≥ 0.85 recall on ordinary personal data, zero false Art. 9 on
infrastructure). Spanish, Italian, Portuguese, Polish, Swedish, Danish and Romanian have terms, but
their recall is not yet measured — treat those as best-effort and check them.
The kinds you’ll see
Each flagged column carries a human label:
⚠ Art. 9
Special category — health, beliefs, ethnicity, biometrics, sexual orientation, trade-union… Stricter rules apply; it has its own count and its own filter.
⚠ Art. 10
Criminal-offence data — processed only under official authority or where the law allows. A separate class from Art. 9.
? unknown
A container column (json, blob) Regixo can’t see into — you confirm what’s inside.
not personal
No rule matched, and nobody has corrected it. Regixo says so rather than leaving the cell blank.
…plus Email · Phone · Name · Address · Date of birth · National ID · Financial (card/IBAN) · IP address · Location · Identifier · Gender · Credential/secret · Employment · Personal detail.
Lineage
Lineage arrows show where data flows. They come from three places, and the map tells you which:
Warehouse (auto) — view → table edges read from the Postgres/Redshift catalog.
dbt — the model ref-graph from your manifest.json.
Asserted by you — cross-system flows a scanner can’t infer (e.g. Stripe → your users table), added with regixo lineage (see Enrich & share).
Open a dataset and its flows draw as a vertical river: Comes from above, the dataset
itself on the trunk, Feeds into below. Every chip reads name · source — so
customers · app-db is never confused with customers · mysql-db — and each
caption says who claims the flow (via dbt, via the warehouse, asserted by you).
The head of each pane counts the reach: 2 direct, or 7 direct · 13 total when
the chain runs deeper (a cycle-guarded closure). A join, a loop, or an endpoint Regixo hasn’t scanned
is stated in words, never left to a guess — and a dashed chip is exactly that: an endpoint someone
claims, that isn’t on the map.
Something looks wrong?
If a column is flagged that shouldn’t be (or missed one that should), you correct it — and the
correction sticks across re-scans. That’s the next page: Classify & correct.
How you know you’ve read the map well
You read the two headline counts and the separate Art. 9 / Art. 10 counts — and
sanity-checked any “0 Art. 9” against what you know your business actually handles.
You opened every source fold and confirmed the sources you expect are all present (a missing fold
means a source didn’t scan — that’s back on the previous
page).
You have a short list of flags that look wrong — the false positives to clear and the missed
columns to add. That list is the input to the next page.
Your next step
Step 4 of 7 — fix a flag the classifier got wrong, and make it stick:
Classify & correct →.