feat(governance): policy backend client, YAML compiler, loader#121
feat(governance): policy backend client, YAML compiler, loader#121aditik0303 wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds the “native” governance policy ingestion path: fetch policy YAML + enforcement mode from the backend, compile YAML into an in-memory PolicyIndex, and cache/prefetch it at runtime startup.
Changes:
- Introduces a governance backend client + policy API client for one-shot policy fetches (fail-open).
- Adds a YAML →
PolicyIndexcompiler that tolerates partial/malformed packs by skipping invalid rules/checks. - Implements a cached loader with optional background prefetch plus extensive unit tests covering fetch/parse/load behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_yaml_to_index.py | Comprehensive tests for YAML → PolicyIndex compilation across supported check types and edge cases. |
| tests/test_policy_api_client.py | Tests for policy fetch skip paths, HTTP failure handling, and JSON body parsing. |
| tests/test_policy_agent_type.py | Tests agent-type selector behavior and URL query parameter composition. |
| tests/test_loader.py | Tests loader caching, prefetch coordination, enforcement mode application, and empty-index diagnostics. |
| src/uipath/runtime/governance/native/policy_api_client.py | Implements policy URL building, one-shot GET, and backend response parsing into PolicyResponse. |
| src/uipath/runtime/governance/native/loader.py | Adds cached loader + background prefetch coordination and enforcement-mode application. |
| src/uipath/runtime/governance/native/backend_client.py | Shared backend URL/header composition, org/tenant resolution, agent-type selector, and safe-call helper. |
| src/uipath/runtime/governance/native/_yaml_to_index.py | YAML compiler from packs/rules/checks into native governance models. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
418fd8f to
14bd3cc
Compare
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… worker failure, default explicit conditions to AND, policy_chars label, importorskip wrapper in agent-type test Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- backend_client/policy_api_client/loader read org/tenant (+ job context) from the environment via runtime-local ENV_* constants instead of importing UiPathConfig. Adds ENV_TRACE_ID. Diagnostic/log messages no longer reference uipath-platform. - _yaml_to_index: convert the parsed logic string to the Logic enum (Check.logic is now typed Logic). - test_loader: assert on env-var names; import reset helper from tests._helpers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
14bd3cc to
acfa5b5
Compare
…their definition site) loader.py imported ENV_ORGANIZATION_ID/ENV_TENANT_ID/resolve_organization_id/ resolve_tenant_id from policy_api_client, which only re-imports them from backend_client — tripping mypy's no_implicit_reexport (4 attr-defined errors). Import them directly from backend_client where they're defined. No runtime change; clears mypy across the stack. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
This PR is crossing the library boundaries.
I raised the same concern on the first PR in this stack: uipath-runtime should stay at the runtime abstraction layer and should not own platform-specific concerns like auth, tenant/org resolution, access tokens, base URL handling, HTTP transport, headers, retries/timeouts or UiPath platform endpoint details.
In this PR, /runtime/policy transport and platform request context are implemented inside uipath-runtime. that duplicates logic already owned by uipath-platform and creates another place where platform auth/config behavior has to be maintained.
uipath-runtime should not own the /runtime/policy transport at all. runtime should only consume a policy source abstraction or already-resolved policy content.
My proposed approach:
- define a small protocol/model in
uipath-core, e.g.GovernancePolicyProvider/GovernancePolicyResponse uipath-runtimedepends only on that protocol and turnspoliciesintoPolicyIndex- uipath-platform` implements the provider using existing platform auth/config/HTTP services (check how the other services are implemented)
- the top-level
uipathCLI wires the platform provider into runtime construction
As a general note:
uipath-core defines contracts
uipath-platform talks to UiPath platform
uipath-runtime handles runtime policy parsing/evaluation
uipath (CLI) composes them
…ovider
Replaces the direct backend HTTP fetch with a GovernancePolicyProvider
indirection so the runtime no longer owns transport, auth, or wire
format. Adds the GovernanceRuntime wrapper and the architecture doc.
- src/uipath/runtime/governance/runtime.py: new GovernanceRuntime(delegate,
policy_provider). Extracts delegate._agent_definition.is_conversational
(depth-capped chain walk), registers the provider, kicks off prefetch.
Passthrough at execute/stream/get_schema/dispose — policy loading only,
no enforcement yet (evaluator slice lands separately).
- src/uipath/runtime/governance/native/loader.py: provider-only loader.
set_policy_provider, set_agent_conversational, prefetch_policy_index,
get_policy_index, clear_policy_cache. Cached PolicyIndex; fail-open on
every failure path (raise / empty / malformed / zero rules / timeout).
- src/uipath/runtime/governance/native/_yaml_to_index.py: drop hardcoded
default clause-id messages ("A.7.4" / "A.8.4" / "A.10.4"); messages
now come from YAML, defaulting to "".
- src/uipath/runtime/governance/config.py: docstrings reworded for the
provider-supplied enforcement mode (no endpoint references).
- Removed src/uipath/runtime/governance/native/policy_api_client.py and
src/uipath/runtime/governance/native/backend_client.py — direct HTTP
fetcher and its shared helpers. Selector + timeout moved into loader.py.
- pyproject.toml: bump uipath-core to ==0.5.21.
- tests: new tests/test_governance_runtime.py (extraction, fail-open,
selector-overwrite regression, prefetch integration), rewritten
tests/test_loader.py for the provider contract, shared StubPolicyProvider
in tests/_helpers.py.
- docs/governance-architecture.md: provider-only design with explicit
'policy loading only, no enforcement yet' staging caveat, module map,
lifecycle diagram, failure-mode table.
ruff / mypy clean, 197 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
55510f9 to
e708f4f
Compare
Stacked PR 2/7 — part of splitting
feat/governance-coreinto reviewable slices. Base:feat/governance-foundation. One logical slice (branch is cumulative so CI is green). Merge in order #1 → #7 and delete each branch on merge so the next PR auto-retargets ontofeat/agentic-governance.feat/governance-corekept untouched as backup.