Refuse another tenant's workflow in the words of one that is not there
Refuses a workflow outside the caller's tenant in the same words as one that is not there, so the client contract (and the HTTP API built on it) stops telling a consumer which workflows the other tenants have.
LocalOrchestraClient::startProcess() asks the tenant question before the engine's and throws REFUSAL_MISSING for a workflow the caller's tenant cannot see. It reuses the engine's own constant rather than repeating its text, so the two answers cannot drift back into being distinguishable. A workflow that is this tenant's still says which of the four reasons applies, because that names the caller's own configuration.
The four refusal templates move from DefinitionResolver (@internal) to WorkflowEngineInterface (@api, which already carries the engine's other public constants). The strings are unchanged; this is what lets the API module reuse one without reaching into an internal class.
Tests: testTheWorkflowOfAnotherTenantIsRefusedAsAnUnknownOne() asserts the two refusals are identical rather than asserting either wording, since the invariant is indistinguishability however it is phrased. It fails without the guard. testTheDisabledWorkflowOfThisTenantStillSaysSo() pins the other direction, so the collapse cannot be widened to a caller's own tenant.
Docs: openapi.yaml states the behaviour on the start endpoint, and multi-tenancy.md gains a "What a refusal may say" section, because this is a rule the whole boundary follows and not a detail of one method.