Commercial Intelligence · Odoo · AI Governance

Where Your Data Comes From: How We Do Commercial Intelligence and How We Measure Intent

Where Your Data Comes From: How We Do Commercial Intelligence and How We Measure Intent

If you received an email from us in the last few weeks, you probably wondered the same thing we would wonder: where did they get my name?

This is the long answer. No marketing euphemisms and none of that comfortable phrase, "our proprietary artificial intelligence system." We are going to show the complete method: what sources we use, what tools, how we score, what we discard, what we record, and where it all ends up stored. The reason for publishing it is simple: if we are going to write to you cold, you have the right to know how we got to you.

There is a second reason, less noble but just as honest: this method is our service offering. The best way to explain what we do with Odoo and with governed AI agents is to show what we do with our own commercial operation.


1. The real problem: most "leads" don't exist

B2B prospecting in 2026 has an arithmetic problem. List-generation tools produce volume with ridiculous ease. Ten thousand records are one click away. And practically none of them mean anything.

Our starting point was an uncomfortable autopsy of our own numbers. We had accumulated thousands of contacts through commercial automation platforms. When we went to audit what was really behind that base, 67% did not fit our ideal customer profile, nearly a third were outside the geography we serve, and the signal the platform called "intent" turned out to be topic matching: if someone mentioned the word "ERP" in a post, the system flagged them as interested in buying an ERP. By that criterion, our own competitors showed up as hot prospects.

That is the point where we decided to build the method from scratch, with an uncomfortable rule at its center:

A signal only counts if we can cite it verbatim and say where it came from.

Everything else — the inferred, the self-declared, the probable — is worth zero. Not "worth little." Worth zero, and it is written that way in the code.

Diagram 1 — Two ways to arrive at a list. Only one leaves an auditable trail.
View Mermaid source
flowchart LR
    A["Volume
10,000 records"] -->|"Old method"| B["'Qualified leads'
by topic matching"] B --> C["Emails sent"] C --> D["Noise"] E["Universe bounded
by ICP"] -->|"Current method"| F["Citable evidence
per record"] F --> G["Hard exclusion
gates"] G --> H["Recorded in Odoo
with source"] style D fill:#7c2d12,color:#fff style H fill:#166534,color:#fff style B fill:#78350f,color:#fff style F fill:#1e3a5f,color:#fff
Diagram 1 — Two ways to arrive at a list. Only one leaves an auditable trail.

2. The complete architecture, at a glance

Before getting into the detail, here is what the whole system looks like. Five layers, each with the job of killing records that should not reach the next one.

Diagram 2 — The architecture. Each layer exists to shrink the set, never to inflate it.
View Mermaid source
flowchart TD
    subgraph L1["1 · SOURCES"]
        F1["DENUE / INEGI"]
        F2["Public web
and technical footprints"] F3["Sector
directories"] F4["Professional
networks"] end subgraph L2["2 · ENRICHMENT"] E1["Decision-maker
identification"] E2["Email
verification"] E3["Infrastructure
reconnaissance"] end subgraph L3["3 · EVALUATION"] R1["5-axis rubric
/ 100 pts"] R2["Catalog of
intent events"] end subgraph L4["4 · GATES"] G1["Hard
exclusions"] G2["Data quality
gate"] end subgraph L5["5 · RECORD"] O1["Odoo · res.partner
18 custom fields"] O2["Tags
and block lists"] O3["Log in
the chatter"] end L1 --> L2 --> L3 --> L4 --> L5 style L1 fill:#0f172a,color:#fff style L4 fill:#7c2d12,color:#fff style L5 fill:#166534,color:#fff
Diagram 2 — The architecture. Each layer exists to shrink the set, never to inflate it.

3. The sources: the free and official stuff first

There is an order, and it is not negotiable. We always start with what is public, official and free, and we only drop down to paid APIs once a record has already survived the cheap filters. It is not a virtue: it is that enrichment APIs charge per credit and our monthly quota is finite — on the order of tens of queries, not thousands.

Diagram 3 — Query order. DENUE has more than 5 million economic units and is free; it always goes before any paid API.
View Mermaid source
flowchart TD
    S0["Candidate record"] --> S1{"Does it exist in
INEGI's DENUE?"} S1 -->|"No"| X1["Discard or
verify by hand"] S1 -->|"Yes"| S2["SCIAN industry,
headcount stratum,
location"] S2 --> S3{"Does the ICP fit
by industry and size?"} S3 -->|"No"| X2["Discard
Cost: $0"] S3 -->|"Yes"| S4["Website:
technical footprint"] S4 --> S5{"Verifiable
technical signal?"} S5 -->|"No"| S6["Still alive,
but no proven pain"] S5 -->|"Yes"| S7["Infrastructure
reconnaissance"] S6 --> S8 S7 --> S8{"Worth the
API credit?"} S8 -->|"Yes"| S9["Decision-maker
enrichment"] S8 -->|"No"| X3["Freeze"] style X1 fill:#7c2d12,color:#fff style X2 fill:#7c2d12,color:#fff style X3 fill:#78350f,color:#fff style S9 fill:#166534,color:#fff
Diagram 3 — Query order. DENUE has more than 5 million economic units and is free; it always goes before any paid API.

The concrete sources:

Layer What we use Why
Economic census DENUE (INEGI) via our own connector Official SCIAN industry, headcount stratum and geolocation. Free.
Public web Corporate site, metadata, subdomains, WHOIS and DNS records The infrastructure a company exposes is evidence a third party can verify; what it says about itself on its home page is not.
Directories Public sector and exporter registries Useful for bounding universes, not for qualifying.
Professional networks Public LinkedIn profiles Roles, tenure and — very useful — verbatim mentions of the software they already use.
Product footprints Scanning of public Odoo installations Identifies version, exposure and open test environments.

We never use, by explicit decision: leaked databases, security breaches, personal emails or private phone numbers. Our technical reconnaissance tool is configured with a whitelist of 24 allowed modules and 23 explicitly forbidden ones, in deny-by-default mode. Search seeds by email address and by phone number are blocked at the configuration level: the tool only accepts a domain or an organization name as a starting point. That is not a setting anyone can change for convenience during a prospecting session — it is the container's base configuration.


4. What we find when we scan public footprints

This is probably the finding that cost us the most and saved us the most.

At the end of July we ran a large exercise scanning public Odoo installations in Mexico, Latin America and the southern United States. The raw result: 121 validated unique domains. A number that, in a conventional sales report, gets presented as "121 new leads."

Once we ran them through the rubric, here is what was really there:

Diagram 4 — 60% of what looked like a market was competition. With dorks in North America the proportion reached 92%.
View Mermaid source
pie showData
    title Real composition of 121 domains with a public Odoo footprint
    "Partners and consultants (direct competition)" : 73
    "Public sector, education, already migrated, test environments" : 20
    "Real candidates" : 28
Diagram 4 — 60% of what looked like a market was competition. With dorks in North America the proportion reached 92%.

Sixty percent were our own competitors. Companies that show up in a "who uses Odoo" scan precisely because they implement it for others. In a later round focused on North America, of 24 new domains, 22 were partners. Ninety-two percent.

If that exercise had ended in a CSV sent to a sales team, we would have written emails offering Odoo support to firms that make their living giving Odoo support. And we would have reported it as "121 prospects worked."

A second finding of the same kind: we had a list of nearly 200 records built around a commercial trigger that had an expiration date — an international event that ended on July 19, 2026. In the August cut, 176 of those 199 records were invalidated all at once, not because the companies changed, but because the reason to talk to them had ceased to exist. Data that ages without warning is worse than not having the data.


5. Profiling a company: the walkthrough of one exercise

When a candidate survives the cheap filter, it enters the full protocol. Here is what a real exercise looks like, step by step.

Diagram 5 — A complete commercial intelligence exercise. Note the last step: we never take a write for granted without reading it back.
View Mermaid source
sequenceDiagram
    autonumber
    participant A as Analyst (agent + human)
    participant M as Vector memory
    participant D as DENUE / INEGI
    participant W as Web and technical OSINT
    participant E as Enrichment APIs
    participant O as Odoo

    A->>M: Do we already know anything about this company?
    M-->>A: Background, prior verdicts, exclusions
    A->>A: Check available quota before spending
    A->>D: Industry, stratum, address
    D-->>A: Official record
    A->>W: Site, subdomains, DNS, software version
    W-->>A: Verifiable technical signals
    A->>A: Map stakeholders with public sources
    A->>E: Only if the case warrants it: verify emails
    E-->>A: Verification status and confidence
    A->>A: Apply rubric and gate
    alt Gate closed
        A->>O: Record profile, score and reason for the block
    else Gate open
        A->>O: Record profile, decision-makers, signals and log
    end
    O-->>A: Confirmation by reading it back, not by the write's "true"
Diagram 5 — A complete commercial intelligence exercise. Note the last step: we never take a write for granted without reading it back.

That last detail matters more than it seems. An automated agent that reports "done, saved" without verifying is an agent that fabricates. Every write to our Odoo is confirmed by reading the record back.


6. Stakeholder mapping: five roles, not a list of names

A contact is not a decision-maker. We aim to understand who decides, who suffers the problem, who can block the purchase, and who would win internally if the project moves forward.

Diagram 6 — The five roles. Without at least the economic and the technical one identified, the case is not ready.
View Mermaid source
mindmap
  root((Stakeholder
map)) Economic buyer Signs the budget Measures in money and risk User Lives the problem daily Source of the real pain Technical evaluator Validates feasibility Can veto on architecture Internal champion Wins if the project moves forward Translates inward Blocker Defends the status quo Sometimes it is the current vendor
Diagram 6 — The five roles. Without at least the economic and the technical one identified, the case is not ready.

The minimum goal is two named decision-makers, each with an email and a phone number, explicitly marking which are verified and which are inferred. An email derived by pattern — guessing [email protected] — is a hypothesis, and it is tagged as such. Nothing is ever sent to a hypothesis.

Here a methodological confession is in order. In August we detected that eleven of our own profiles said "zero people identified." It was false. The search had been done filtering only by company-type records, without dropping down to the child contacts. There were 36 people there, including three general directors. Eleven scores rose once we fixed it, and one changed category entirely. The error was ours, in our own query, and it stayed invisible for two weeks because the result — "there's no one" — confirmed what we already assumed.

It is exactly the failure the rubric is designed to catch, and it caught us.


7. The quality gate: when NOTHING gets produced

This is the part that distinguishes the method from a document generator. The gate is evaluated before drafting any commercial material.

Diagram 7 — The gate. If it doesn't close, the deliverable is the report of what's missing. Forcing the production of commercial material just to complete the exercise is forbidden.
View Mermaid source
flowchart TD
    C0["Finished intelligence
profile"] --> C1{"2+ named decision-makers
with email AND phone?"} C1 -->|"No"| N1["Deliverable = report
of what's missing"] C1 -->|"Yes"| C2{"Concrete and verifiable
technology priority
signal?"} C2 -->|"No"| C2b{"Is there an explicit reason
to proceed anyway?"} C2b -->|"No"| N1 C2b -->|"Yes"| C3 C2 -->|"Yes"| C3{"Unresolved
red flag?"} C3 -->|"Yes"| N2["Block + permanent
tag"] C3 -->|"No"| Y1["Gate open"] N1 --> R["Next-step
recommendation"] N2 --> R style N1 fill:#78350f,color:#fff style N2 fill:#7c2d12,color:#fff style Y1 fill:#166534,color:#fff
Diagram 7 — The gate. If it doesn't close, the deliverable is the report of what's missing. Forcing the production of commercial material just to complete the exercise is forbidden.

The literal instruction in our protocol reads: "do not force the generation of commercial documents just to complete the exercise." It sounds obvious. In practice it is the first thing that breaks when there is pressure on numbers.


8. Measuring intent: the event catalog

We arrive at the core of the matter. What is a buying intent?

The industry's conventional answer is some combination of email opens, clicks, web visits and social mentions. We reject all four. An open email can be a mail client pre-loading images. A click can be a corporate security filter. A mention of "ERP" on LinkedIn can be a competitor.

Our taxonomy distinguishes ten types of signal, and only some count as intent:

Diagram 8 — Ten types of signal, three destinations. Each is classified with a confidence level and a mandatory verbatim citation.
View Mermaid source
mindmap
  root((Signal
taxonomy)) Count as intent Explicit need Pain signal Project signal Frustration with vendor Budget or timeline Count as context Referral opportunity Authority opportunity Alliance signal Do not count Noise Blocked by privacy
Diagram 8 — Ten types of signal, three destinations. Each is classified with a confidence level and a mandatory verbatim citation.

And this is the event catalog with its weights. It is literally like this in the code that computes the scores:

Diagram 9 — The catalog of intent events. The four at the bottom are exactly the ones the industry sells as "buyer intent."
View Mermaid source
flowchart LR
    subgraph P1["HIGH WEIGHT · demonstrated commitment"]
        A1["Invoice paid · 20"]
        A2["Meeting held · 12"]
        A3["Quote sent · 10"]
        A4["Demo presented · 10"]
    end
    subgraph P2["MEDIUM WEIGHT · the prospect asked for something"]
        B1["Requested meeting · 9"]
        B2["Requested quote · 9"]
        B3["Due diligence question · 8"]
        B4["Declared pain · 8"]
        B5["Technical talk · 8"]
    end
    subgraph P3["LOW WEIGHT · there is conversation"]
        C1["Replied to email · 6"]
        C2["Email thread · 6"]
        C3["Declared interest · 5"]
        C4["Direct channel opened · 5"]
        C5["Own phone contact · 4"]
        C6["Event confirmed · 3"]
    end
    subgraph P0["ZERO WEIGHT · not intent"]
        D1["Touch delivered · 0"]
        D2["Touch received · 0"]
        D3["Topic match · 0"]
        D4["Open without reply · 0"]
    end

    style P1 fill:#166534,color:#fff
    style P2 fill:#1e3a5f,color:#fff
    style P3 fill:#78350f,color:#fff
    style P0 fill:#7c2d12,color:#fff
Diagram 9 — The catalog of intent events. The four at the bottom are exactly the ones the industry sells as "buyer intent."

Note what sits in the zero-weight box: having delivered an email, having received one, topic matching and the open without a reply. Those are the four metrics on which most demand-generation software rests. For us they are worth zero, and that decision cost us having to rebuild the entire dashboard.

The five-intent rule

On top of that catalog sits the operational definition we set on July 17, 2026, and which today is a whole field in our CRM:

A contact is not a lead just for replying. A candidate becomes a qualified lead only when it accumulates five or more observable buying intents — meetings, quotes sent, technical talks, demos. A reply, on its own, is worth zero.

And it comes with a second half that gets cited far less and matters just as much economically:

On reaching five intents, we stop prospecting that candidate.

The rule cuts waste at both ends. It stops us chasing whoever never gave a signal, and it stops us spending prospecting effort on whoever already gave enough. Both errors cost the same.

Diagram 10 — The state machine. A record only advances with citable evidence; it moves backward on its own, from the absence of it.
View Mermaid source
stateDiagram-v2
    [*] --> Suspect: Enters the universe
    Suspect --> Candidate: Decision-maker identified
with valid channel Suspect --> Exclude: Hard gate Candidate --> Opportunity: 1st observable intent
with citation Candidate --> CoolingOff: 0 intents
after the cadence Opportunity --> Opportunity: 2nd, 3rd, 4th intent Opportunity --> Lead: 5th intent Opportunity --> CoolingOff: The signal goes quiet CoolingOff --> Candidate: Re-entry after 30 days Lead --> [*]: Stops being prospected note right of Lead This article stops here end note
Diagram 10 — The state machine. A record only advances with citable evidence; it moves backward on its own, from the absence of it.

9. The full rubric: 100 points, 5 axes

Verified intent is one of five axes. Here is how the hundred points break down:

Diagram 11 — Breakdown of the 100 points. "Inferred pain" is worth zero: if we can't cite the evidence, it does not exist for the score.
View Mermaid source
flowchart TD
    T["Total score · 100"] --> E1["ICP FIT · 30"]
    T --> E2["VERIFIABLE PAIN · 20"]
    T --> E3["DECISION-MAKER · 25"]
    T --> E4["VERIFIED INTENT · 20"]
    T --> E5["ACCESS COST · 5"]

    E1 --> E1a["Sector · 12"]
    E1 --> E1b["Geography · 6"]
    E1 --> E1c["Size · 6"]
    E1 --> E1d["Complexity · 6"]

    E2 --> E2a["Legacy version
confirmed · 12"] E2 --> E2b["Fragile stack · 5"] E2 --> E2c["Regulatory pressure · 3"] E2 --> E2d["Inferred pain · 0"] E4 --> E4a["Only observable events
with citation and source"] style E2d fill:#7c2d12,color:#fff style E4a fill:#166534,color:#fff
Diagram 11 — Breakdown of the 100 points. "Inferred pain" is worth zero: if we can't cite the evidence, it does not exist for the score.

There is a lightweight three-axis version — stakeholders, technical signal and scale fit, 0 to 3 each — that we use to curate whole segments in batches. The final tier is High with 7 out of 9 or more, Medium between 4 and 6, Low with 3 or fewer. With a rule that overrides the score: if the company is not the type of entity we are looking for, the red flag cancels the prioritization no matter how many points it added up, and it forces removing the tag, not just noting the problem in a comment.

That distinction between "noting it" and "removing the tag" cost us three incidents. A verdict written in prose inside a text field does not stop the record from reappearing in the next segment. Only the tag stops it. We documented three reappearances of the same blocked company before fixing the process.

What happens when you change the rubric

It is worth showing the real effect. Moving from the July rubric to the August one — the one that demands citable evidence — an account we had at 88 out of 100 dropped to 36. The company didn't change. What changed was what we accepted as proof.

In the same cut, 351 records evaluated produced 38 hard exclusions. Thirty-eight records that, until that day, counted as pipeline.

Diagram 12 — The quadrant that saved us the most decisions. The fourth quadrant is the one the measurement discipline makes visible: accounts with a lot of accumulated effort and zero signal.
View Mermaid source
quadrantChart
    title Effort invested against signal obtained
    x-axis "Low effort" --> "High effort"
    y-axis "No signal" --> "With citable signal"
    quadrant-1 "Work it hard"
    quadrant-2 "Quick win"
    quadrant-3 "Leave at rest"
    quadrant-4 "Stop: bottomless pit"
    "Account with 5 intents": [0.72, 0.93]
    "Account with 3 intents": [0.55, 0.68]
    "Candidate with decision-maker": [0.30, 0.42]
    "Multi-touch without reply": [0.75, 0.08]
    "OSINT domain without a person": [0.16, 0.05]
Diagram 12 — The quadrant that saved us the most decisions. The fourth quadrant is the one the measurement discipline makes visible: accounts with a lot of accumulated effort and zero signal.

10. The hard gates: who we never write to, ever

Regardless of the score, there are categories that leave the universe by decision, not by calculation.

Diagram 13 — Hard gates. None admits an exception for a high score.
View Mermaid source
flowchart TD
    R["Evaluated record"] --> G1{"Is it an Odoo partner
or consultant?"} G1 -->|"Yes"| X1["EXCLUDE
Direct competition"] G1 -->|"No"| G2{"Public sector,
state-owned or education?"} G2 -->|"Yes"| X2["EXCLUDE
Permanent gate"] G2 -->|"No"| G3{"Legal or
reputational risk?"} G3 -->|"Yes"| X3["EXCLUDE
Signed decision,
not by omission"] G3 -->|"No"| G4{"Current version
with no proven pain?"} G4 -->|"Yes"| X4["EXCLUDE
Nothing to offer"] G4 -->|"No"| G5{"Requested not
to be contacted?"} G5 -->|"Yes"| X5["BLOCK LIST
Permanent"] G5 -->|"No"| P["Continues to scoring"] style X1 fill:#7c2d12,color:#fff style X2 fill:#7c2d12,color:#fff style X3 fill:#7c2d12,color:#fff style X4 fill:#78350f,color:#fff style X5 fill:#450a0a,color:#fff style P fill:#166534,color:#fff
Diagram 13 — Hard gates. None admits an exception for a high score.

Two notes on this. The first: exclusion for legal or reputational risk is documented as a signed decision, not as an oversight. If an account leaves the universe for that reason, it is written down who decided it and why. The second: keeping two block lists that don't talk to each other is a silent way of violating the will of someone who already asked not to be contacted. It happened to us, we detected it, and we consolidated the lists into Odoo's native record.


11. The three defects that make a segment reach no one

Before a segment is considered ready, three specific failures are checked. All three are data problems, not copy problems, and all three are silent.

Diagram 14 — The three defects. The third is the dangerous one: it produces no error, it produces the wrong message.
View Mermaid source
flowchart TD
    S["Segment with
a broad domain"] --> D1{"Defect 1
Does the parent record
have an email?"} D1 -->|"No"| F1["The email lives in the
child contact.
The segment comes out empty."] D1 -->|"Yes"| D2{"Defect 2
Is the name the
company's name?"} D2 -->|"No"| F2["Title scraped from the site.
The dynamic greeting
comes out as 'Login | My Website'."] D2 -->|"Yes"| D3{"Defect 3
Are the editable body and
the sent body
identical?"} D3 -->|"No"| F3["The editor looks fine
and old text goes out.
The one that bites in silence."] D3 -->|"Yes"| OK["Admissible segment"] style F1 fill:#7c2d12,color:#fff style F2 fill:#7c2d12,color:#fff style F3 fill:#450a0a,color:#fff style OK fill:#166534,color:#fff
Diagram 14 — The three defects. The third is the dangerous one: it produces no error, it produces the wrong message.

The first is more common than one would expect. In our own base, 64% of the company records had no email on the parent record — the emails lived in the child contacts. A segment built on the company model, without dropping down to the people, would have gone out to a tiny fraction of its real audience, and the report would have said "sent successfully."

And a hygiene rule about which email is admissible. Only three origins pass: a named decision-maker with direct verification, a decision-maker email published verbatim by the company itself, or a corporate generic published by the company. No pattern-derived email passes without verification.


12. Where it all ends up: the landing in Odoo

Here is where the intelligence exercise ends. Everything above exists to produce a record in our Odoo that a human being can audit without having to ask anyone for explanations.

We don't use a parallel spreadsheet, nor an external platform, nor a free-notes field. We created 18 custom fields on the contacts model, with their own view, grouped into four blocks.

Diagram 15 — The data model. Two fields deserve attention: `x_tg_fuente_dato` (where it came from) and `x_tg_intenciones_detalle` (the log with the source of each recorded intent).
View Mermaid source
erDiagram
    RES_PARTNER ||--o{ CHILD_CONTACT : "has decision-makers"
    RES_PARTNER ||--o{ TAG : "classified by"
    RES_PARTNER ||--o{ CHATTER_MESSAGE : "log of"
    RES_PARTNER ||--o| CRM_OPPORTUNITY : "generates"
    BLOCK_LIST ||--o{ RES_PARTNER : "suppresses"

    RES_PARTNER {
        int x_tg_scoring_total "0-100"
        int x_tg_eje_stakeholders "0-3"
        int x_tg_eje_senal_tecnica "0-3"
        int x_tg_eje_ajuste "0-3"
        bool x_tg_bandera_roja "overrides tier"
        int x_tg_intenciones_n "five-intent rule"
        text x_tg_intenciones_detalle "log with source"
        char x_tg_decisor_nombre "person"
        char x_tg_decisor_cargo "role"
        char x_tg_decisor_canal "valid channel"
        text x_tg_dolor_verificable "verbatim citation"
        char x_tg_version_odoo "technical signal"
        text x_tg_siguiente_accion "commitment"
        char x_tg_fuente_dato "traceability"
        date x_tg_fecha_scoring "expiration"
        selection x_tg_tier "high medium low"
        selection x_tg_clasificacion "lead to exclude"
        selection x_tg_icp "target profile"
    }
    CHILD_CONTACT {
        char name
        char role
        char verified_email
        char confirmation_grade
    }
    TAG {
        char tier_and_scoring
        char red_flags
        char permanent_gates
        char data_origin
    }
Diagram 15 — The data model. Two fields deserve attention: `x_tg_fuente_dato` (where it came from) and `x_tg_intenciones_detalle` (the log with the source of each recorded intent).

The four fields that do the heavy lifting:

On top of that, a tagging system that materializes the decisions — scoring tiers, permanent gates by sector, unviable-email flags, batch origin — and a log in each record's chatter with the complete intelligence report. That log is the important point: the conclusion and its evidence live glued to the record, not in a loose document someone has to go find.

Diagram 16 — Four months of corrections. Every milestone was born from a measured error, not from an idea.
View Mermaid source
timeline
    title Evolution of the method, from email opens to citable evidence
    section May 2026
        First ICP profile and 0-to-100 scoring : Tracking pixels rejected by design
        Initial signal taxonomy : Rule of separating the observed from the inferred
    section June 2026
        Technical OSINT layer with whitelist : Diagnosis of the real funnel
        The first empty funnel is discovered : Many touches, zero recorded signals
    section July 2026
        The 5-intent rule is set : A reply, on its own, is worth zero
        Audit of the inherited base : 60 percent of the raw OSINT was competition
    section August 2026
        100-point rubric with inferred pain at zero : Complete reclassification of the universe
        Migration to native Odoo fields : The evidence lives next to the record
Diagram 16 — Four months of corrections. Every milestone was born from a measured error, not from an idea.

13. The tools, named and surnamed

Since we are teaching the method, we teach the workshop too. All of this operates through standardized connectors that the AI agents consume under explicit permissions.

Diagram 17 — The workshop. Odoo is the only system of record; everything else is an instrument.
View Mermaid source
flowchart LR
    subgraph AG["AGENTS · with per-tool permissions"]
        AG1["Commercial
intelligence protocol"] AG2["Segment
curation protocol"] AG3["Pipeline review
and competitive intelligence"] end subgraph CN["CONNECTORS"] C1["DENUE · INEGI"] C2["Own technical
reconnaissance"] C3["Email
verification"] C4["People
enrichment"] C5["Controlled
browser"] C6["Web search
and reading"] end subgraph MEM["MEMORY AND CONTROL"] M1["Vector memory"] M2["Traces and
observability"] M3["Dated audit
logs"] end subgraph SR["SYSTEM OF RECORD"] S1["Odoo"] end AG --> CN --> SR AG <--> MEM MEM --> S1 style SR fill:#166534,color:#fff style MEM fill:#1e3a5f,color:#fff
Diagram 17 — The workshop. Odoo is the only system of record; everything else is an instrument.
Function Tool Governance note
Official economic census Own connector to DENUE (INEGI) Free. Always first.
Technical reconnaissance Flowsint, self-hosted Whitelist of 24 modules, 23 forbidden, deny by default. Email and phone seeds blocked.
Email verification Hunter.io Shared quota of 50 queries per month. Hard stop at 95%.
People enrichment Apollo.io, Clay, Snov.io Sensitive personal data disabled by default. One enrichment per decision-maker, not per curiosity.
Assisted browsing Controlled Chrome For sources that can't be read without executing the page.
System of record Odoo (self-hosted and in the cloud) The only destination for conclusions.
Agent memory Mem0 and Qdrant Avoids repeating research already done and burning quota twice.
Observability Grafana, Langfuse, Prometheus What each agent did, when and at what cost.
Automation n8n Orchestration of recurring tasks.

Two governance decisions worth spelling out, because they are the ones we get asked about most:

No tool writes to production on its own. The agents produce drafts. The write to Odoo goes through review, and every write is verified by reading the record back. There is no exception for urgency.

We shut down an entire commercial platform. We operated an AI lead-generation tool for months. On auditing its notion of a "hot lead" we discovered it was topic matching of social posts, with an arbitrarily declared strength, and it included our own competitors. We shut it down. It didn't fail technically: it did exactly what it promised. The problem was what it promised.


14. What's in our records today

To close the circle with real transparency, here is what exists today in our Odoo as the product of everything above:

And a ratio that says more than any other figure: of the entire evaluated universe, the vast majority is classified as suspect or candidate. That is: we explicitly acknowledge that most of our records still have not demonstrated interest in anything. Calling them "leads" would be lying to ourselves.

Diagram 18 — The complete journey. An excluded record is documented too: knowing why we said no is worth as much as knowing why we said yes.
View Mermaid source
flowchart LR
    subgraph ORI["Origin"]
        O1["Appears in a census
or public web"] O2["Survives the filter
of sector and size"] end subgraph INV["Investigation"] I1["People and technical
signals are sought"] I2["The verifiable is verified,
the inferred is flagged"] end subgraph JUI["Judgment"] J1["Passes through rubric
and gates"] J2["The reason is recorded,
even if excluded"] end subgraph REG["Record"] R1["Lands in Odoo with
score, source and date"] R2["Auditable by any
human on the team"] end ORI --> INV --> JUI --> REG style ORI fill:#0f172a,color:#fff style REG fill:#166534,color:#fff
Diagram 18 — The complete journey. An excluded record is documented too: knowing why we said no is worth as much as knowing why we said yes.

If you are in those records

This article ends here on purpose. We are not going to describe what we do next with a qualified record — that is a matter for the conversation we have with you, if we have one.

What we do want to make clear is the following. If you received an email from us, it was not because we bought a database. It was because your company appears in an official economic census, or because your public infrastructure emits a technical signal we know how to read, or because someone on your team published something relevant on an open professional profile. All from publicly accessible sources. No breaches, no leaked data, no personal emails.

And if you'd rather we didn't have you: write to us and you leave our records the same day, permanently, in the system and not in a note. If you'd rather see what we have about your company, ask for it and we'll send you the whole thing. It's your information.

It seems to us that a company that is going to propose governing your data should start by showing how it governs its own.


Transgenia implements and operates Odoo with governed AI agents. Write to us at [email protected] · Privacy notice

← Back to Blog