From the journal

Building a regulatory change monitor: what broke, and what it taught us

Horizon watches official regulator publications and tells compliance teams when something changes. On 13 August 2026 it monitored 141 pages across 53 authorities in 20 jurisdictions: the European Union institutions, the United Kingdom, and 18 EU member states.

Illia ProkopievCo-Founder and CEO9 min read

How the system works, in outline

Licentium Horizon fetches each monitored page on a schedule. It extracts the readable text, produces a fingerprint of that text, and compares the fingerprint with the one stored from the previous visit. A difference triggers a comparison of old text against new. A language model then summarises what changed, and subscribers receive an email carrying a link to the regulator's own page.

Four of those steps can fail quietly, and the fingerprint step is the reason. We fingerprint the text our extractor produces, not the raw page. Any change to how we read a page therefore changes every fingerprint at once, and a changed fingerprint is indistinguishable from a regulatory change. That single property governs almost every engineering decision described below.

The failure that does not announce itself

Monitoring software fails in two ways, and only one of them is loud.

The loud way is an error. A page returns 404, a fetch times out, a health dashboard turns red, and somebody investigates that day.

The quiet way does more damage. Suppose our text extraction returns a site's navigation menu instead of the page body. That menu reads identically tomorrow. No change is detected, no alert goes out, and every dashboard still marks the source healthy. A regulator can publish a rule change into that page and nobody hears about it.

We found sources sitting in exactly that condition, some of them for months. Any buyer evaluating a monitoring service should ask how the vendor detects it, because the symptom is silence rather than an error message.

Five extraction faults, found in a single audit

On 11 August we audited our own text extraction against live regulator pages. Five faults came out of one day of work.

Government sites built on older .NET tooling wrap an entire page body inside a single form element. Our extractor discarded form elements, on the reasonable theory that a form is a search box or a newsletter signup. Extraction returned zero characters for Spain's securities market regulator and for three Central Bank of Ireland pages covering crypto-asset rules.

Choosing the wrong part of a page cost us a British policy statement. The Financial Conduct Authority publishes its cryptoasset financial promotion rules on a page carrying two article elements. The first holds about 100 characters of consultation dates. The full 5,114-character statement sits elsewhere on the same page. We monitored the 100 characters, then parked the source for being too thin to use.

A cookie-banner filter deleted genuine regulatory content. Publishing platforms label pages by subject in the underlying markup, so a data protection authority writing about GDPR produces a page labelled for GDPR. Our filter matched that label and removed 2,458 of 2,585 characters from Malta's data protection authority. We monitor eight data protection authorities, so one fault stripped the most relevant material across our whole privacy and AI segment.

Our comparison baseline was empty on a third of the estate. The worker stored a fingerprint of each page, but on days when nothing changed it did not store the text. 42 of 114 live sources reported success while holding no text at all. Their first real change would have been compared against an empty string, handing the summariser an entire page instead of the part that moved.

Withdrawals produced no alert. When a regulator removes guidance, a comparison looking for added text finds none. Our filter classified the result as noise and advanced the fingerprint past it, which meant the event could never be noticed afterwards. Withdrawn guidance is a regulatory event, and we were skipping it in silence.

All five passed every health check we had at the time. That shared property, rather than any individual bug, changed what we measure.

What two outside reviewers found

We commissioned two independent adversarial reviews of the extraction code and told both to attack it. They worked separately and returned 17 findings each, converging on several of the same weaknesses.

One finding we had missed completely. A widely deployed cookie-consent plugin records consent state on the page's own body element rather than on the banner. Our filter could therefore have deleted an entire document instead of a notice.

Both reviewers recommended replacing our extractor with an established open-source library. We declined. Swapping extractors would have changed every fingerprint on the same deploy, and every subscriber would have received an alert claiming that every regulator had acted on the same morning. A correctness improvement that emails hundreds of false regulatory alerts to compliance officers is not an improvement.

A second opinion that cannot overrule the first

Instead of replacing our extractor, we added a second one that reads the same page and cannot affect what subscribers receive. We record where the two disagree and route the disagreements to a person.

The comparison is asymmetric by design. When the second extractor finds far more text than ours, someone reviews the page. When ours finds more, nobody reviews it, because the second extractor is built for article pages and shortens listing pages as intended. Treating both directions alike would bury the real signal under differences we already expect.

After 149 observations across 142 sources, the two extractors agreed on 115. Thirteen showed the expected shortening on listing pages. Twenty were feeds that the second extractor correctly declined to parse. One was flagged for a human to read.

That one arrived on 13 August, on the Hellenic Capital Market Commission's circulars page, which we had added to the system the same morning. Our extractor produced 3,102 characters and the second produced 11,703, a gap wide enough to suggest we were missing most of the page.

We read both outputs against the rendered page. Ours was complete: the breadcrumb, the heading, every circular from number 60 down to number 48, and the pagination controls at the foot of the list. The additional 8,600 characters in the second version were the site's navigation menu, which runs to several hundred links on hcmc.gr and which our extractor removes on purpose.

So the flag was wrong, and the way it was wrong is worth recording. Our comparison rule treats a much larger second reading as evidence that we missed content. On a site with a very large menu, the second extractor produces more text while producing worse text. We are adding a link-density check before a page reaches a reviewer. One false alarm in 149 observations is an acceptable rate, and finding out why it fired cost an hour.

Checking too rarely is its own fault

Not every fault lives in the parsing. Each source carries an expected publication cadence, and a configuration error had left a group of them on a monthly schedule when they should have been read daily. Nothing in the system complained, because every one of those sources was being fetched successfully, just far too seldom.

Correcting the schedule surfaced nine genuine regulatory changes inside a single cycle. They included European Securities and Markets Authority questions and answers on crypto-asset markets, European Banking Authority material on stablecoin authorisation, and European Commission publications on AI Act governance. Some had been invisible to subscribers for four weeks.

Coverage, and why country accuracy decides its value

Monitored pages grew from 98 to 141 over the past fortnight. During August we added Austria, Belgium, Czechia, Denmark, Sweden, Portugal, Greece and Cyprus, taking the jurisdiction count from 12 to 20. Spain and Italy went from nothing to working coverage earlier in the same month.

Volume by itself would not be worth much. A German payments firm has little use for an Estonian circular, so a service that cannot say which country a change belongs to produces one undifferentiated European feed. Country accuracy is the reason we expanded by jurisdiction rather than by page count.

We add a source only after fetching it and reading what comes back. Of 26 sources added on 13 August, 16 returned usable content on the first check and two failed openly, with the remainder still queued. A feed address that looks plausible but has never been read is worse than a written record that none was found, so we keep the list of paths we tried without success.

The two failures behaved differently. Denmark's financial supervisor returned 404 to our servers for a page that renders normally in an ordinary browser. The Bank of Greece returned 403. Both are parked with a written note explaining what we saw, and neither country lost coverage, because other authorities in each still work.

Regulators that decline automated traffic

Thirteen monitored pages across five authorities refuse our servers outright: the Bank of Lithuania, the Malta Financial Services Authority, the Malta Digital Innovation Authority, a Lithuanian ministry, and now the Bank of Greece. Each of them serves the same pages to an ordinary browser without complaint.

We have not tried to disguise our traffic. Solving challenges, rotating identities or imitating a human visitor would be circumvention, and we will not build it. Our alternative path attaches a verifiable cryptographic signature identifying us as a declared crawler operated by a named company. Whether a signed request is then admitted depends entirely on how each regulator has configured its own rules.

That approach costs us Malta and Lithuania for the moment. We record those authorities as uncovered rather than implying otherwise, and we treat a continued refusal as the regulator's answer.

What to ask any monitoring vendor

Three questions separate a service that works from one that appears to.

How do you detect a source that has quietly stopped returning real content? A vendor without an answer is relying on the absence of errors, which is not the same as the presence of coverage.

What happens when a regulator withdraws guidance instead of publishing something? Removal is harder to detect than addition and carries as much weight for a compliance team.

Illia Prokopiev

Written by

Illia Prokopiev

Co-Founder and CEO

Illia is the Managing Partner and founder of Licentium. With over 11 years of practice, he has guided innovators through cross-border M&A deals and the disputes that follow, combining transactional skill with courtroom resolve. Admitted to the bar in 2017, he pivoted early to Web3, serving as legal advisor to prominent crypto projects and carrying AML/MLRO duties that anchored complex token, DAO, and compliance questions on solid regulatory ground. Certified in money laundering prevention and an active crypto investor, Illia blends market intuition with a global network of specialists, enabling Licentium to untangle licensing knots for crypto and AI ventures anywhere in the world.