Where a model processes prompts, and who made it

A model node (nodeType:LanguageModel) carries two marks, and they answer two different questions:

Mark Field Question Values
๐Ÿ‡ช๐Ÿ‡บ / ๐ŸŒ / โ” Processing dataResidency (+ dataRetention) Where are our prompts processed? Eu, Global, Unknown โ€” open: a module may add a region code such as CH
๐Ÿณ๏ธ Origin modelOrigin (+ modelMaker) Where is the model's maker based? ISO country code: CN (Z.ai, Moonshot, DeepSeek, Qwen), US (OpenAI, Anthropic, xAI, Meta, Google), FR (Mistral), CA (Cohere), any other ISO code

The two marks are independent. GLM 5.3 is made in China and can be processed in the EU; Claude is made in the US and is processed wherever Anthropic or Azure route it. Both are open string-constant vocabularies (policy open-vocabulary-string-constants): DataResidency and ModelOrigin in MeshWeaver.AI.

The rule: only Eu is EU

DataResidency.IsEu is true for Eu and nothing else. Only an unset or blank mark becomes Unknown. Any other value stays as authored, because the vocabulary is open: CH stays CH, and so does a typo. None of them ever counts as EU, and each satisfies only a requirement that names exactly that value. DataResidency.Satisfies(actual, required) never admits Unknown, even when the requirement itself names Unknown.

The mark describes the route, not the model:

Route Mark
eu.openrouter.ai (OpenRouter's EU region: only EU provider endpoints) Eu
openrouter.ai, api.openai.com, api.anthropic.com, the makers' own public APIs Global
Azure, DataZoneStandard or regional Standard SKU in an EU-region resource Eu, but only when declared
Azure, GlobalStandard Global, declared
Azure, undeclared Unknown: the same host serves every SKU, so the host alone proves nothing
Claude in Microsoft Foundry Global. Foundry offers Claude as Global Standard, plus a Data Zone for the US only. There is no EU zone.

Where the marks come from

The model node's own dataResidency is the only value any consumer reads. The picker badge, the provider page, tier resolution and the round's refusal all read it, so they cannot disagree. The emitters seed it with ModelProvenance.Seed, and a value authored on the node always wins:

  1. Declared by the deployment. {Section}:DataResidency and {Section}:DataRetention apply to every model of that catalog section, e.g. AzureFoundry__DataResidency=Eu for a DataZone-only account.
  2. Implied by the endpoint (DataResidency.FromEndpoint), for the hosts in the table above.
  3. Otherwise unset, which reads Unknown.

The maker and its country are inferred from the id. The org slug is tried first (z-ai/, moonshotai/, anthropic/), then the family token (Kimi-K2.6, claude-haiku-4-5, DeepSeek-V4-Flash). An id nothing recognises stays Unknown; the platform never guesses.

A ModelProvider node carries dataResidency / dataRetention too. This is a seed for the models the provider creates, never a verdict. The built-in provider node is create-if-absent, so a mark added to its configuration later reaches its model children, which are synced, and not the provider node itself.

Where the marks show

Requiring EU: fail closed

A requirement is set in one of two places. When both are set, both apply.

Who How Effect
The instance AI:RequiredDataResidency=Eu (env AI__RequiredDataResidency) The picker hides the instance's models not marked Eu. The default model, tier resolution and Auto skip them. The round refuses them, and so does the image generator.
An agent front matter requiredDataResidency: Eu (AgentConfiguration.RequiredDataResidency) Tier and Auto resolution for that agent skip non-Eu models. A round of that agent on one is refused, including a hand-off to it.

The refusal happens before any prompt leaves the process. The user sees a localized sentence naming the model, its mark and who requires EU, and the refusal is logged at Warning. An explicit pick of a non-admitted model is healed onto an admitted one, the same way an unusable pick is healed. When none is admitted, the round is refused; it never falls back to a Global model. A bare model id that matches several catalog entries with different marks reads Unknown: which entry would serve it cannot be promised.

"No endpoint" never means "a US default". Under the instance switch, every request is also checked at the point where it is built, by ChatClientCredentialResolver.InstanceRouteRefusal (called by the OpenAI, Azure OpenAI, Anthropic and Azure Foundry factories and by the image generator). A request with no endpoint is refused, because the OpenAI SDK would fall back to api.openai.com and the image generator would use the same host. A request whose endpoint is a known global host is refused too. An Azure host passes this check: the model node's own mark was already checked. Listing a provider's models (ProviderModelLister, against the maker's API) sends no prompts and is not gated.

What the instance switch does NOT cover:

Code review (policy code-review-eu-only): the reviewer's model is bound to Provider/OpenRouterEU (eu.openrouter.ai) with a pinned providerRouting region, which the review-binding change owns (MeshWeaver.Plugins#2446). Its DataResidencies.EU value "EU" reads as Eu here, because the comparison is case-insensitive. The agent-level marker requiredDataResidency: Eu is not set on Governance/Agent/reviewer yet, and that is deliberate. That agent also reviews every governed activity, and no model on the control instance is marked Eu today. Declaring the requirement now would refuse every review, including the approvals the elimination below needs. Set it in the same change that marks the EU review model.

Pinned by:

What a fleet audit found (2026-09-27)

A read-only audit covered every deployment record on the control instance, the LanguageModel/ModelProvider nodes on each portal instance, every Azure AI Services account (az cognitiveservices account deployment list, subscription explicit), and the OpenRouter EU region (https://eu.openrouter.ai/api/v1/models/<id>/endpoints). The per-instance rows are operational data and are not kept in this generic page; what generalises is below.

No chat or embedding model served by any instance was EU-only. The only EU-only rows were an in-cluster speech model (a self-hosted Whisper pod) and two Azure deployments that no instance referenced (one DataZoneStandard, one regional Standard).

Bring-your-own keys live as ModelProvider nodes at {user}/_Memex/<Provider>, with their models at {user}/_Provider/<Provider>/<model> and the key stored enc:v1:. They are never seeded Eu: a known global host reads Global, and anything else reads Unknown. Row-level security hides other users' BYOK nodes, so an audit counts only the auditor's own.

Not established by the audit

  1. The running pods' configuration. The records are not the pods. Overlay-only helm keys and live environments were not read.
  2. Embeddings on client instances. One client record declares no Embedding__* key; another client estate has no record on the control instance, so which embedding deployment it uses is probable but not proven.
  3. Retention. It was not checked whether any Azure account has approved modified abuse monitoring (zero retention), whether OpenRouter has account-level ZDR or provider filters, or what Inceptron's terms are. On GLM 5.3, the EU Mistral endpoint is tagged nvfp4, not zdr.
  4. Inceptron's location. OpenRouter lists it in its EU region, and that is the only basis for calling it EU.
  5. GitHub Copilot CLI residency was not researched, so it is Unknown. The build instance's mesh was not reachable.

A second compliant provider (2026-10-04)

On 2026-10-04 one OpenRouter key's daily limit (HTTP 403: Key limit exceeded) closed the control instance's only Eu/ZDR provider at 14:47Z, and every review and agent round waited until the next UTC midnight. The admission falls back by default (AgentAdmission ยง7), but a fallback keeps the round's marks โ€” an Eu round moves only to an Eu model, a ZDR round only to a ZDR one, and the instance's AI:RequiredDataResidency binds every target โ€” so it needs a second provider that carries the same marks. Under this page's rules, none does yet.

What qualifies. A model node marked dataResidency: Eu and carrying the same dataRetention as the round it stands in for (ZDR on every model of the OpenRouter EU route, declared by its section). The marks must be true of the route, not hoped for.

Candidate Reading Admissible on an EU-only instance?
Anthropic direct (api.anthropic.com) Global by its endpoint (DataResidency.FromEndpoint) โ€” a maker's public API, which this page never reads as EU No. The round refuses it before sending, and the fallback never offers it. It may serve only an instance or lane with no EU requirement.
Claude in Microsoft Foundry Global Standard, plus a US-only Data Zone (above) No.
Azure, GlobalStandard deployments (every chat deployment on our EU-region account, measured) Global No.
Azure, DataZoneStandard in the EU-region resource Eu once declared. The region offers it for tier members gpt-6-sol, gpt-6-luna, Mistral-Large-3, DeepSeek-V4-Flash (az cognitiveservices model list); the only such deployment today is an older reasoning model in no tier Residency yes, retention no โ€” see below.
A second key on the OpenRouter account The same EU route, the same marks Yes, but it is the same provider and the same account: it survives a per-KEY limit, not an account-credit limit or an OpenRouter outage.

Retention on Azure is not ZDR by default. Azure OpenAI's abuse monitoring stores prompts and completions for up to 30 days (in the resource's geography) unless Microsoft has approved modified abuse monitoring for the resource, which then lists the capability ContentLogging with value false. Our account lists no ContentLogging capability (read with az cognitiveservices account show โ€ฆ --query properties.capabilities), so a DataZone deployment there is Eu with retained prompts: it must be marked with its true retention, and the fallback then does not offer it to a ZDR round.

The provider node on the control instance (Provider/AzureFoundry) has a key bound but no endpoint and no models, so it serves nothing: a request with no endpoint is refused at build on an EU-only instance (InstanceRouteRefusal).

Proposed (the maintainer's decision โ€” creating cloud resources is not an agent's call)

  1. Deploy the tier members as DataZoneStandard in the EU-region resource: gpt-6-sol (heavy), gpt-6-luna (light), and Mistral-Large-3 or DeepSeek-V4-Flash (standard). The cheapest useful set is gpt-6-sol + gpt-6-luna: they are the SAME models the EU route serves, so the fallback takes them first.
  2. Apply for modified abuse monitoring on that resource. Only once the account shows ContentLogging: false may its models be marked dataRetention: ZDR. Until then they are marked with their real retention, and they keep the fleet alive only for rounds that do not require ZDR: on the control instance, none, because every EU-route model declares it. Admitting EU processing with EU-stored abuse monitoring for some lane would be a policy decision, not a marking.
  3. Seed them as their OWN catalog section, marked per model. Never set AzureFoundry__DataResidency=Eu on a section that also lists GlobalStandard deployments: a section declaration marks every model of the section. Prefer a governed CreateNode standard per model (as Dispatch's models are created) with dataResidency: Eu and the measured dataRetention on the node, and an endpoint that is the EU resource's.
  4. Meanwhile: raising the OpenRouter key's daily limit, or a second key with its own limit, keeps the same compliant route and needs no new residency claim.

Pinned by DefaultAlternativesTest (the fallback keeps the marks; with no compliant second provider a round waits rather than leave the route; with one, a closed key fails over to it).

Proposed elimination (not executed)

Every change below is a record change or an Azure deployment change. Each goes through a governed Hosting/InstanceAction / Governance/Activity on the control instance, and each needs the maintainer's approval. Nothing here has been applied.

The target tiers, as the maintainer decided, are all served through eu.openrouter.ai on our OpenRouter account:

tier model EU providers
heavy anthropic/claude-opus-5.5 Amazon Bedrock eu-west-1, Google Vertex europe
standard, review z-ai/glm-5.3 Inceptron, Mistral
light openai/gpt-6-luna Azure (eu)
utility mistralai/mistral-small-2603 Mistral (eu)

These apply to every instance that runs on our OpenRouter account โ€” Systemorph's own portal instances and the SME client instances hosted on them, which have no key of their own.

An enterprise client with its own OpenRouter account is out of this scope. Its models are its own to choose. They are marked the same way, with processing decided by its own route.

  1. Route the tiers above through the EU region. Use an OpenRouterEU provider section at https://eu.openrouter.ai/api/v1, which is marked Eu by its endpoint. It is config-seeded, and its chart and Hosting rendering are owned by the fleet-switch work.
  2. Drop or mark the models with no EU route: moonshotai/kimi-k3, openai/gpt-5.2, google/gemini-3.1-pro-preview, google/gemini-3.7-flash, deepseek/deepseek-v4-pro, x-ai/grok-4.6 and every Qwen model. None of them has an EU provider on OpenRouter. The tiers above replace them; any that stay offered are marked Global.
  3. Embeddings: deploy text-embedding-3-small as DataZoneStandard on our Azure AI Services account (offered in swedencentral) and point Embedding__Endpoint there. It is the same model, so no re-index is needed. The alternative is mistralai/mistral-embed on eu.openrouter.ai, which does need a re-index.
  4. Claude in Foundry has no EU zone. The heavy tier moves to Claude through eu.openrouter.ai. Any Foundry Claude still offered is marked Global.
  5. Azure GlobalStandard deployments on our accounts: redeploy as DataZoneStandard where swedencentral offers it (gpt-5-mini, gpt-5.4, Mistral-Large-3, DeepSeek-V4-Flash 2026-04-23). Mark the rest only. Delete the unreferenced deployments.
  6. Declare the marks on the records: {Section}__DataResidency per provider section (Anthropic__DataResidency=Global; AzureFoundry__DataResidency=Eu only once its deployments are DataZone or regional), and AI__RequiredDataResidency=Eu on each instance that must be EU-only. ๐Ÿšจ Measured on core main: the portal chart renders none of these keys yet, and it renders no OpenRouter__Endpoint or OpenRouterEU__* either. Its ConfigMap names every key explicitly, so a record that sets them reaches no container until the chart adds them.

Incidental findings from the audit, not about residency: