CONNECTOR GAPS — r1.4 cross-domain sweep
Date: 2026-08-26
Scope: the 15 sources named in whitepaper amendment r1.4 §14.1 ("Unified Connector Gateway"). This register exists because that section's draft claimed all 15 "normalize through one gateway into canonical envelopes" — code verification found that claim true for less than half of them.
Method: read-only sweep of src/shared/virtuoso_models/transforms/mappers.py, miz-oki-adk-agents/kg-canonical-ingest/mappers/, services/service-marketing-connectors/, services/measurement-rails/, services/intent-*-extender/, miz-oki-adk-agents/boss/connector_gateway/tools.py, services/service-canonical-ingestion/.
There is no single named gateway
Three separate, non-unified mechanisms exist:
service-canonical-ingestion(Cloud Run) —POST /api/v1/ingestwraps payloads in the liveCanonicalEventEnvelope(schema v3.5.1,contracts/mizoki_contracts/envelope.py). Callers must pre-normalize before calling it; it has noMAPPERS[source]dispatch of its own.MAPPERS[source](raw) → ingest_gate(event, upsert_fn)— an in-process library dispatch (src/shared/virtuoso_models/journey_event.py:198; dict atsrc/shared/virtuoso_models/transforms/mappers.py:434-440), the "no side doors" path named in.claude/rules/03-canonical-architecture.md. This produces a different envelope shape (src/shared/virtuoso_models/schemas/journey-event.json) thanservice-canonical-ingestion.miz-oki-adk-agents/boss/connector_gateway/tools.py— a Boss-agent outbound action tool registry (gmail.search, drive.fetch, github.create_issue, bigquery.query, neo4j.cypher, calendar.create_event). This is not an ingestion path; it does not touch either envelope.
Connector-by-connector status
| Source | Status | Path | Evidence |
|---|---|---|---|
| Google Ads | LIVE (code) | service-marketing-connectors adapter + MAPPERS |
services/service-marketing-connectors/direct_connectors.py:511 (GoogleAdsAdapter); mappers.py:434-436 |
| Meta Ads | LIVE (code) | service-marketing-connectors adapter + MAPPERS |
direct_connectors.py:466 (MetaAdsAdapter); mappers.py:435 |
| SendGrid | LIVE (code) | MAPPERS + separate cell mapper |
mappers.py:436 (map_sendgrid); miz-oki-adk-agents/kg-canonical-ingest/mappers/email.py |
| Shopify | PARTIAL, fail-closed | MAPPERS + extender |
mappers.py:437 (map_shopify); services/intent-shopify-extender/main.py (SHOPIFY_WEBHOOK_SECRET gate) |
| GA4 | PARTIAL, fail-closed | service-marketing-connectors adapter + extender |
direct_connectors.py:549 (GA4Adapter); services/intent-ga4-extender/main.py:39-44 (fails closed on unset GA4_EXPORT_DATASET) |
| Klaviyo | PARTIAL, aggregate-only by design | MAPPERS + connector |
mappers.py:437 (map_klaviyo); services/service-marketing-connectors/klaviyo_connector.py:145-200; excluded from bucket path (bucket_connectors.py:79, "no-per-person-nodes decision") |
| The Trade Desk (TTD) | PARTIAL, fail-closed | service-marketing-connectors adapter + extender |
direct_connectors.py:693 (TradeDeskAdapter); services/intent-pullers-extender/main.py (TTD_REDS_BUCKET gate) |
| OpenRTB | IN BUILD, narrow | MAPPERS (journey lane only) + separate cell mapper |
mappers.py:436 (map_openrtb); miz-oki-adk-agents/kg-canonical-ingest/mappers/openrtb.py. No HTTP adapter in direct_connectors.py — not reachable via service-canonical-ingestion |
| BigQuery | not a source — destination | landing table for canonical events | CANONICAL_EVENTS_BQ_TABLE in erasure/ingestion code; never an inbound connector |
| Vertex AI | not a source — inference backend | LLM backend behind virtuoso_call |
src/shared/virtuoso_models/vendor_adapters.py:132-162; never feeds the envelope as a data source |
| Graph storage | not a source — projection target | Firestore-backed KG | services/service-canonical-ingestion/projector_kg.py projects envelopes → KG; no reverse ingestion path found |
| Gmail | not wired — Boss outbound tool only | connector_gateway/tools.py:18-27 |
gmail.search/gmail.read — no wiring to MAPPERS/ingest_gate or service-canonical-ingestion |
| Drive | not wired — Boss outbound tool only | connector_gateway/tools.py:29-33 |
drive.fetch |
| GitHub | not wired — Boss outbound tool only | connector_gateway/tools.py:34-38 |
github.create_issue |
| Calendar | not wired — Boss outbound tool only | connector_gateway/tools.py:48-52 |
calendar.create_event |
Summary
- 3 LIVE, 4 PARTIAL/fail-closed, 1 IN BUILD/narrow — 8 of 15 are genuine, wired ingestion connectors.
- 7 of 15 are not ingestion sources at all: 4 are Boss-agent outbound action tools never connected to ingestion (Gmail, Drive, GitHub, Calendar), 3 are ingestion destinations/backends misdescribed as sources (BigQuery, Vertex AI, graph storage).
- No component in the repo is named "Unified Connector Gateway." The nearest real things are
service-canonical-ingestionand theMAPPERS[source] → ingest_gatedispatch — two separate mechanisms with two different envelope shapes, not one gateway.
Register items
These are added to the Feature Coverage Matrix Gap Register (§10, rows G-25 through G-28):
- G-25: CLOSED 2026-08-26 —
content_qadidn't scope repo-rootdocs/marketing//docs/product/;scripts/check_canon_docs.pynow gates them in CI (content-truth-gatejob). (build) - G-26: Three coexisting envelope schemas (v1.0.0 superseded, v3.5.1 live via
mizoki_contracts, journey-event.json viaMAPPERS) have no convergence date beyond "tracked at DATA-001." (build) - G-27:
service-canonical-ingestionandMAPPERS[source] → ingest_gateare two parallel, non-unified ingestion paths with different envelope shapes; no single gateway exists despite marketing prose using that phrase. (build) - G-28: OpenRTB has no HTTP adapter and is unreachable via
service-canonical-ingestion— journey-lane mapper only. (build) - G-29: GitHub is not a connector at all. There is no catalog entry, no
adapter, and no mapper — the only
githubstrings in service code are a Boss-agent outbound action (github.create_issue, §3 above) and an unrelated token check incoding-moa. Raised 2026-08-31 when "bolt on proper GitHub and Google properties" was scoped: the Google half was a real, blocked gap (closed the same day — seeTENANT_ONBOARDING_CHECKLIST.md§5.6), the GitHub half had nothing to bolt onto. Deferred by owner decision rather than designed speculatively; a future build needs the ingest question answered first (what GitHub activity is a marketing/intent signal, and for whom) before a catalog entry can enumerate honest fields. (build)