# Integration call routing (`IntegrationCallRequest`) is dead on both ends **Date:** 2026-07-22 · **Status:** OPEN (decision needed: wire or delete) · **Severity:** Low (no runtime impact — the path cannot be reached) · **Area:** Central–Site Communication ## What "Pattern 4: Integration Routing" — `CommunicationService.RouteIntegrationCallAsync` → `SiteEnvelope(IntegrationCallRequest)` → `SiteCommunicationActor` → an integration handler — is plumbed end to end but connected at neither end. - **No producer.** `RouteIntegrationCallAsync` (`CommunicationService.cs`, "Pattern 4") has **zero callers** in `src/` or `tests/`. It is the only one of `CommunicationService`'s command methods with none. - **No handler.** `SiteCommunicationActor` forwards to `_integrationHandler` when one is registered, but `RegisterLocalHandler(LocalHandlerType.Integration, …)` appears **only** in `SiteCommunicationActorTests.cs`. `AkkaHostedService` registers the other three handler types (`Artifacts`, `EventLog`, `ParkedMessages`) and never this one. So if anything ever did call it, the site would answer `IntegrationCallResponse(Success: false, Error: "Integration handler not available")` (`SiteCommunicationActor.cs`, Pattern 4) — and the two tests that exercise the path both register the handler themselves first, which is why the suite has never noticed. Do not confuse this with the **Inbound API**'s routed-site-script path, which is live, tested, and uses different messages entirely. This is a separate, unused routing pattern that predates it. ## Why it is recorded rather than fixed Found during the recon for the ClusterClient→gRPC transport migration ([`docs/plans/2026-07-22-clusterclient-to-grpc-plan.md`](../plans/2026-07-22-clusterclient-to-grpc-plan.md), T0.2), which had to enumerate every command crossing the site↔central boundary. Of the **29** command types, this is the one that is excluded: **28 migrate to the gRPC contract.** Porting it would mean designing a proto contract, a `oneof` slot and round-trip mapper tests for a verb no caller can invoke and no site can service — and enshrining it on a wire format whose evolution rules are additive-only, so an unused RPC slot is permanent. Deleting it during a transport migration would mix an unrelated behavioural change into a change whose whole value is that behaviour is identical. Hence: excluded from the contract, behaviour untouched, decision deferred to its own change. ## Decision needed Either: 1. **Delete** — remove `RouteIntegrationCallAsync`, the `IntegrationCallRequest`/`Response` messages, the `SiteCommunicationActor` receive block, `LocalHandlerType.Integration`, and the three tests that cover them. This is the default if no consumer is planned. 2. **Wire** — register a real integration handler on site nodes and give the method a caller. This only makes sense if there is a requirement it serves; none is recorded in `docs/requirements/`. Whichever is chosen, do it **before Phase 4** of the migration, since Phase 4 deletes the Akka transport underneath this path. If it is still dead at that point, option 1 is forced. ## Filing To be filed as a Gitea issue on `dohertj2/scadabridge` by the repo owner — this note is the in-repo record of the finding and of the migration exclusion it justifies.