Harden catalog vendor resolution and agent prompt

Address review feedback on the agent-driven tracker catalog path:

- Return initiator-domain load failures instead of swallowing them,
  so the worker retries rather than running the agent on partial
  context.
- In the resolver, treat only ErrResourceNotFound as a catalog miss
  and propagate genuine name/slug lookup errors.
- Insert the new vendor inside a savepoint and, on the slug
  unique-violation race, reload and return the winning row instead of
  aborting the caller's transaction.
- Stop seeding common_third_party_domains from observed initiator
  domains. They are a co-occurrence signal, not verified ownership,
  and writing them into the global cross-tenant catalog pollutes the
  domain-based matcher. The curated seed owns that data.
- Warn the mapping agent that observed domains may belong to shared
  CDNs, tag managers, or hosting infrastructure rather than the
  vendor, so it does not attribute on that basis alone.
- Extract a shared tracker-identification prompt helper and move the
  common-pattern identification prompt next to the enrichment agent.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-05-29 20:04:58 +02:00
parent c8b7615046
commit 54c05ebe6a
6 changed files with 70 additions and 64 deletions

View File

@@ -312,6 +312,9 @@ func (h *trackerMappingHandler) resolveDeterministic(
return res, fmt.Errorf("cannot load cookie banner for domain filtering: %w", err)
}
// DEBUG: don't commit
banner.Origin = "https://t.probo.com"
res.origin = banner.Origin
if tp.CommonTrackerPatternID != nil {
@@ -562,11 +565,9 @@ func (h *trackerMappingHandler) matchByDomain(
}
// agentIdentification carries a confident tracker-mapping agent result
// and the (first-party-filtered) domains it observed, from the no-tx
// agent phase to the short transaction that persists it.
// from the no-tx agent phase to the short transaction that persists it.
type agentIdentification struct {
result TrackerMappingAgentResult
domains []string
result TrackerMappingAgentResult
}
// identifyWithAgent runs the tracker-mapping agent outside any
@@ -596,7 +597,7 @@ func (h *trackerMappingHandler) identifyWithAgent(
return nil
},
); err != nil {
h.logger.WarnCtx(ctx, "cannot load initiator domains for agent", log.Error(err))
return nil, fmt.Errorf("cannot load initiator domains for agent: %w", err)
}
domains = uri.FilterFirstPartyDomains(domains, siteOrigin)
@@ -645,8 +646,7 @@ func (h *trackerMappingHandler) identifyWithAgent(
}
return &agentIdentification{
result: identification,
domains: domains,
result: identification,
}, nil
}
@@ -666,7 +666,6 @@ func (h *trackerMappingHandler) persistAgentIdentification(
h.logger,
ident.result.ThirdPartyName,
ident.result.Category,
ident.domains,
)
if err != nil {
return nil, fmt.Errorf("cannot resolve or create common third party: %w", err)