feat(contrib): add cross-border data-policy router recipe - #2530
Merged
happyhuman merged 7 commits intoAug 18, 2026
Conversation
The env-vars CI check requires every os.getenv/os.environ read in the recipe's source to have an uncommented declaration in .env.example. ALLOW_ORIGINS, LOGS_BUCKET_NAME, OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, GENAI_TELEMETRY_PATH, COMMIT_SHA, OTEL_TO_CLOUD, and K_SERVICE were commented out or missing entirely, which the checker treats as undeclared. Uncomment them with blank default values, following the same declared-but-blank convention used in core/python/long-horizon-harness's .env.example — blank means "unset" and the code applies its existing local-dev-safe default, so runtime behavior is unchanged.
janrockdev
force-pushed
the
contrib/cross-border-data-router
branch
from
August 17, 2026 21:38
bb90248 to
76c9dac
Compare
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
happyhuman
reviewed
Aug 17, 2026
- Reword README pytest command row (integration tests excluded by default) - Add missing license header to app_utils/__init__.py - Fix doubled gs:// scheme in telemetry log hint - Log a warning instead of silently swallowing Cloud Logging init failure - Drop stale Terraform reference in fast_api_app.py comment - Add geographic_location to cards.py docstring's param list - Fix eu_processor jurisdiction EU-WEST -> EU for consistency with its residency list and sibling cards; fixes silent excluded_jurisdictions miss - Fix engine.py docstring: two-stage -> three-stage - Simplify redundant compliance_tags guard in _score - Drop dead ScoredCandidate agent_id placeholder; _score now takes agent_id directly instead of the caller rebuilding it - Rename us_pii test to match its actual financial classification - Add missing uk_processor unit test coverage
happyhuman
approved these changes
Aug 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
contrib/python/cross-border-data-router, a Python ADK recipe demonstrating a common enterprise compliance problem: deciding which regional agent is legally allowed to process a piece of data, based on where that agent says it operates.A root orchestrator receives a data-processing request (a classification like
PIIplus an origin region), evaluates it against a registry of regional processor agents, and only then delegates the work — or refuses outright if no agent qualifies. Eligibility is read directly off each candidate's reala2a.types.AgentCardvia a customcapabilities.extensionsentry, since the core A2A spec has no built-in notion of jurisdiction or data residency.Why this recipe
I searched the repo first for an existing sample that evaluates policy and routes based on an agent's declared location/jurisdiction, and found none:
AgentCardusage in the repo (core/python/long-horizon-harness) builds/serves a card but never reads location off one.python/agents/global-kyc-agentroutes UK vs. US sub-agents, but by an LLM reading the company being checked out of free text — not metadata declared by the candidate agent itself.long-horizon-harness's tool-call guardrails,core/python/safety-plugins) means something different: gating a single agent's own actions, not choosing between agents.This recipe fills that gap with a pattern modeled on OpenEAGO (repo), a FINOS Labs specification for jurisdiction-aware governance of multi-agent workflows. OpenEAGO isn't a published Python package, so this is a from-scratch implementation of the pattern it describes (two-stage hard-filter-then-score agent selection), not a dependency on it — credited and linked in the README.
What's in it
app/policy/cards.py— a static registry of three regional processor cards (eu_processor,uk_processor,us_processor), each a reala2a.types.AgentCardcarrying jurisdiction/data-residency metadata via anAgentExtension.app/policy/engine.py— the routing policy: Stage 1/2 hard filters (data residency, jurisdiction exclusion) that scoring can never override, then a weighted score among survivors. No candidates surviving means an explicit rejection, never a silent fallback to a non-compliant agent.app/agent.py+app/sub_agents/*— an ADKLlmAgentorchestrator that calls the policy tool first, then delegates to the approved regional sub-agent viaAgentTool.tests/unit/test_policy_engine.py,tests/unit/test_tools.py— cover the hard filters, preference scoring, and the reject-rather-than-fallback path directly.Testing
Run locally from the repo root:
Also manually verified
uv run adk run appanduv run uvicorn app.fast_api_app:app --reloadboth start and route correctly against a live Gemini API key.