If you understood it, it was badly explained

We say it back home, in Cameroon: “if someone explains Cameroon to you and you understand it, they explained it badly.” A news-watching robot is the opposite: if it turns an article down and you cannot tell why, it is the badly built one. Published on 5 September 2026.

In short: most monitoring tools swallow everything and sort it out afterwards with a language model. That is expensive, and it fails quietly. We do the reverse: we decide on the title, which is free, and we write down the reason for every refusal. Five parts, each a few dozen lines long.

Part 1 — the robot gives its real name

A robot dressed up as a browser ends up blocked, and it deserves to be. Ours announces who it is and where to find out more. One line, sent to every site it visits.

The line it announces: code-nomi-nomi-veille/1.0 (+https://matourdecontrole.fr ; news-watching robot)
A name, and an address to look it up. Nothing else. No e-mail shouted at every site, no fake “Mozilla”.

No e-mail address shouted at every site, no fake “Mozilla”. An identified robot is accepted; a masked one gets banned. It really is that simple.

Part 2 — the subject gatekeeper

An article's title is free: we already have it from the news feed. So we decide before fetching the full text. Two word lists kept inside, and one rule.

The rule fits in one sentence: keep a title that touches a followed subject, drop one that touches none, and always write down the reason in the logbook. The word lists stay inside: publishing them would hand out the recipe for crafting a title that fools the sorting.

The detail that matters: the decision always returns a reason. Never a silent refusal. The robot's logbook keeps the trace: “IGNORED — no subject of interest in the title — TITLE: …”. So a decision can be challenged, and the list corrected.

A trap already paid for: searching for a short word without anchoring it to a word boundary. Take a made-up example: follow the word “key”, and you will find it inside “monkey” — so every zoo article passes as a useful one. The fix is one character: the word-boundary mark in a search pattern.

Part 3 — the queue that does not forget

A site that answers badly once may answer well tomorrow. The first version struck failed articles off the list: they never came back. That is marking a lost parcel as delivered. Now a failure is a record: three attempts, then “abandoned”, and that abandonment is written down in plain sight.

Part 4 — the private page

The result lives on an internal page. In Odoo, the door holds with one word in the route declaration:

@http.route("/tour/cockpit/veille", type="http", auth="user")
def page(self, **kw):
    ...

auth="user" means: nobody but a signed-in user. Better still, our tower does not say “please log in”, it answers “this page does not exist”. A stranger does not even learn that the page is there. The test that proves it compares against a page already in service: both must answer the same way.

Part 5 — the page lets an agent read it

This is the new part. Since 2026, a browser lets a page put its own functions on the table as named tools. The agent no longer guesses where to click: it asks.

modelContext.registerTool({
  name: "nouvelles_ia",
  description: "Returns the articles kept by the news-watching robot…",
  inputSchema: {
    type: "object",
    properties: {
      sujet:   { type: "string" },
      source:  { type: "string" },
      combien: { type: "integer" },
    },
  },
  execute: async ({ sujet, source, combien }) => ({ … }),
});

Three things make it useful. Every article returned carries its own address, so the agent can check. A word with no match returns an empty list — never a patched-together answer. And the logic is pure: it works on a list handed to it, touching neither disk nor screen, so it can be tested outside the browser.

Wire this in too: a counter. Every call to the tool leaves one line in the server log — what was asked, never who asked. Otherwise you will never know whether an agent uses it at all.

The trap that cost half an hour

After going live, the page worked one time in eight. The stylesheet answered “never heard of it”, then “here you go”, with no visible logic. The cause: the server runs four workers — four copies sharing the visitors. Each keeps in memory the list of files it knew at start-up. A module added later only exists for those that reloaded.

The diagnosis did not come from a hunch: we asked for the same file eight times in a row. Seven refusals, one success. A number settles what an opinion only debates.

Worth keeping: a useful news-watching robot is not the one that gathers the most. It is the one that says why it refuses, that does not forget its failures, and that cites its source. The rest is just volume.
🔭