Regixo docs
🔧 For the engineer·Step 3 of 7 — Read the map·see the whole journey ↗
Data catalog · engineer

Read the map

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 it The 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.

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:

StepOn app-db / customersWhat you read, and decide
1 · Openregixo open → the Map at localhost:4319.The workbench opens on one line of plain English; nothing is picked yet.
2 · CountsThe 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 · FlagsOpen 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 · SourceThe 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 · DecideA 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_datasetsget_datasetget_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

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
Regixo data catalog · free & local

Data map

63 datasets · 170 personal-data columns

re-scan · stays local
Show

app-db / app / customers

● 5 personal
Source
app-db · Postgres · scanned 28h ago
Rows
Columns
7 · 5 personal
Classified by
7 auto
DB owner
regixo

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.

ColumnTypePersonal data
created_attimestamp with time zone optionalnot personal
Correct
A mechanical fix, never a legal judgement. It overrides Regixo’s detection, survives every re-scan, and is logged in What changed.
date_of_birthdate optional● Date of birth by field name
Correct
A mechanical fix, never a legal judgement. It overrides Regixo’s detection, survives every re-scan, and is logged in What changed.
emailtext required● Email by field name
Correct
A mechanical fix, never a legal judgement. It overrides Regixo’s detection, survives every re-scan, and is logged in What changed.

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:

CollectedFromNotes
Tables, columns, data types, nullabilityinformation_schemaAll SQL databases. VIEWs are catalogued as datasets too.
Row-count estimates + owning DB rolepg_class.reltuplesPostgres/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_rewritePostgres/Redshift only. Relation names, never SQL-text parsing.
Personal-data flagscolumn names + typesThe 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.

TierConfidenceWhat it catches
Deny-list1.0 (hard-stop)Special category (Art. 9) and criminal-offence (Art. 10) terms — e.g. health_status, diagnosis, =race, conviction_date.
Name rule0.9The common kinds by column name — email, phone, name, address, national_id, financial, ip, …
Regex0.7Backstop patterns for email / phone / ssn·nino·tax_id.
Your patterns0.7Anything you add in regixo.yml pii.extraPatterns.
Type rule0Opaque 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_idtrace, 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. 9Special category — health, beliefs, ethnicity, biometrics, sexual orientation, trade-union… Stricter rules apply; it has its own count and its own filter.
⚠ Art. 10Criminal-offence data — processed only under official authority or where the law allows. A separate class from Art. 9.
? unknownA container column (json, blob) Regixo can’t see into — you confirm what’s inside.
not personalNo 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:

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

REGIXO — documentation · every flag shows the rule that matched · Glossary