-
Notifications
You must be signed in to change notification settings - Fork 3
Comparing changes
Open a pull request
base repository: UiPath/uipath-runtime-python
base: main
head repository: UiPath/uipath-runtime-python
compare: feat/governance-audit
- 19 commits
- 23 files changed
- 4 contributors
Commits on Jun 27, 2026
-
feat(governance): enforcement-mode config, policy models, deps
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 79fd38f - Browse repository at this point
Copy the full SHA 79fd38fView commit details -
fix(governance): address PR review — use logger on invalid mode, drop…
… forward refs in docstrings, guard backend_client import in conftest Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for bb77290 - Browse repository at this point
Copy the full SHA bb77290View commit details -
fix(governance): address review on enforcement-mode config and models
- config.py: enforcement mode no longer reads the UIPATH_GOVERNANCE_MODE env var directly (the backend /runtime/policy response is the source); default is AUDIT. Mode state lives in a holder object instead of a module global (no `global` statements). The test-only reset helper moved out to tests/_helpers.py so test concerns stay in the test tree. - models.py: Check.logic is now the Logic(str, Enum) instead of a free-form string; tidy the CheckContext.model_name field. - pyproject: add dependency upper bounds (pyyaml<7, vaderSentiment<4, chardet<8); remove the [[tool.mypy.overrides]] block. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 319c5fb - Browse repository at this point
Copy the full SHA 319c5fbView commit details -
fix(governance): consume EnforcementMode from uipath-core
EnforcementMode is a shared governance contract, so it now lives in uipath.core.governance (uipath-core 0.5.19) and is re-exported from config.py — runtime callers keep importing it from one place, but the value type is owned by the lower abstraction level (per radu's review). Bumps the uipath-core floor to 0.5.19. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 2a34075 - Browse repository at this point
Copy the full SHA 2a34075View commit details -
feat(governance): policy backend client, YAML compiler, loader
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for f05dfaf - Browse repository at this point
Copy the full SHA f05dfafView commit details -
fix(governance): address PR review — don't cache empty PolicyIndex on…
… 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>
Configuration menu - View commit details
-
Copy full SHA for 87c4f21 - Browse repository at this point
Copy the full SHA 87c4f21View commit details -
fix(governance): decouple backend/policy client from uipath-platform
- 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>
Configuration menu - View commit details
-
Copy full SHA for 297193e - Browse repository at this point
Copy the full SHA 297193eView commit details -
fix(governance): import env constants/resolvers from backend_client (…
…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>
Configuration menu - View commit details
-
Copy full SHA for 4000928 - Browse repository at this point
Copy the full SHA 4000928View commit details -
feat(governance): provider-only policy loading via GovernancePolicyPr…
…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>Configuration menu - View commit details
-
Copy full SHA for be6e666 - Browse repository at this point
Copy the full SHA be6e666View commit details -
refactor(governance): instance-scope PolicyLoader; explicit is_conver…
…sational Addresses radu's review on PR #121 — collapses three architectural boundary concerns into the loader/runtime layers. 1. PolicyLoader is now instance-scoped, not module-globals. Each GovernanceRuntime constructs its own loader carrying its own provider, cache, prefetch state, and conversational selector. uipath eval can spin up multiple runtimes in parallel without them clobbering each other's policy state. 2. is_governance_enabled() reads removed from the runtime layer. The decision "should governance attach?" belongs to the wiring layer (uipath CLI) — it chooses whether to construct GovernanceRuntime at all. Inside the loader the contract is purely "provider present → load policies; provider missing → empty PolicyIndex". The feature flag itself stays in uipath-core. 3. _extract_is_conversational and its delegate-walking deleted. GovernanceRuntime now takes is_conversational explicitly as a keyword arg; the wiring layer (which knows the agent type) passes it in. Runtime no longer reaches into _delegate._agent_definition private attrs. Plus two correctness fixes called out in the readiness re-check: - clear_cache() vs in-flight prefetch worker race: worker now checks _prefetch_event is event before publishing self._policy_index so an orphaned worker can't clobber the just-cleared cache. - _load_from_provider takes the narrowed provider as a parameter instead of asserting self._provider is not None — the bandit B101 "assert stripped under -O" finding is now gone. Tests rewritten around PolicyLoader instances; cross-instance isolation pinned; orphan-worker race regression test added; conftest autouse reset fixture removed (no module state to clean). 187 pass, ruff/mypy/bandit clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 62e8612 - Browse repository at this point
Copy the full SHA 62e8612View commit details -
refactor(governance): instance-scope enforcement mode on PolicyLoader
Addresses radu's follow-up on PR #121 (discussion r3465934815): the enforcement mode was still process-level scoped via config._state, defeating the point of the loader instance-scoping when uipath eval runs parallel runtimes with mixed-mode policies. - PolicyLoader now owns _enforcement_mode and exposes it via the enforcement_mode property (defaults to AUDIT when no provider response has supplied a mode) - _load_from_provider writes the instance field instead of calling the global set_enforcement_mode - config.py deleted entirely: _state / _EnforcementModeState / get_enforcement_mode / set_enforcement_mode are gone. No production consumers outside the loader; canonical EnforcementMode lives in uipath.core.governance Tests: - _helpers.reset_enforcement_mode dropped (no global to reset) - test_enforcement_mode_default rewritten around PolicyLoader.enforcement_mode; new test_two_loaders_carry_independent_enforcement_modes pins the cross-instance isolation invariant - test_governance_runtime / test_loader drop the reset fixture and the get/set imports; mode-persistence test exercises two consecutive loads on a single loader 188 passed, ruff/mypy/bandit clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 13cd366 - Browse repository at this point
Copy the full SHA 13cd366View commit details -
feat(governance): audit pipeline — manager, console + traces sinks
Adds the audit pipeline that records governance evaluations: an AuditManager that fans out per-evaluation records to registered sinks (console + traces), with per-instance lifecycle (one ThreadPoolExecutor + atexit hook keyed via a WeakSet of live managers — same shape the later GuardrailCompensator slice reuses). Sinks ----- - Console sink for local development and CLI runs. - Traces sink that emits an OTel span per evaluation; severity is mapped from the matched rule's enforcement mode (audit / enforce / guardrail_fallback) so downstream traces UIs can filter by it. Companion changes pulled in via the main-merge on this branch ------------------------------------------------------------- This branch was kept in sync with main during review; the diff therefore includes the following work that originated in other PRs and will already be merged by the time this lands: - Workspace hydration primitives (hydration, hydrator, registry_store, workspace; from PR #131). - ``execution_source`` derived field on the runtime context (from PR #132). Co-Authored-By: Aditi Kumari <aditi.kumari@uipath.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 7e4ef8d - Browse repository at this point
Copy the full SHA 7e4ef8dView commit details
Commits on Jun 29, 2026
-
docs(governance): scope audit docstrings to runtime layer
Address PR #122 review: docstrings and comments referenced external or higher-layer implementation details (uipath-core exporter, UIPATH_* env vars, UiPathSpan, uipath-agents-python SpanType, governance-server, Orchestrator UI, cross-product spec sections). Reworded to describe only what the runtime layer owns. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for c4e7958 - Browse repository at this point
Copy the full SHA c4e7958View commit details -
refactor(governance): drop async-mode dispatch from AuditManager
Switches the audit pipeline to synchronous sink dispatch on the caller's thread. Sinks that need to keep I/O off the hot path own their own batching — the OTel traces sink already rides on `opentelemetry-sdk`'s `BatchSpanProcessor`, which handles export off-thread. Removed from `AuditManager`: - `async_mode` / `queue_maxsize` constructor params - the background worker thread, queue, shutdown event - `_start_worker` / `_worker_loop` / `_drain_queue` / `_emit_sync` - per-instance pid tracking and the fork-rebuild path - `_AuditManagerCleanupRegistry` + the module-level singleton - the `contextvars.copy_context()` snapshot used to thread OTel context across the worker hop (no longer needed — caller's thread already carries the live span) - `flush(timeout=...)` queue-drain wait Result: `emit()` is a lock-protected snapshot + per-sink try/except with the existing 10-failure circuit breaker. `flush()` and `close()` are thin per-sink loops; `close()` is idempotent. `TracesAuditSink` drops the explicit `context=context.get_current()` arg to `tracer.start_as_current_span(...)` — sync dispatch means the current OTel context is already the agent's live span, so governance spans attach as children without cross-thread plumbing. `AuditSink` docstring example rewritten to demonstrate the recommended pattern (enqueue in `emit`, drain on a sink-owned daemon thread) instead of synchronous `requests.post`, which contradicted the new class-level guidance. Tests updated to match: dropped atexit / WeakSet-GC / fork-rebuild / contextvars-propagation cases; added side-effect-free-construction, default-sink registration, bare-construction, close-clears-state, and close-idempotence cases. Net diff: -606 / +249 LOC. No external consumers — grep across `uipath-runtime-python`, `uipath-python`, and `uipath-langchain-python` for `AuditManager(`, `async_mode`, `queue_maxsize`, `_cleanup_registry`, `.flush(timeout` returns zero hits outside the test files updated in this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 85f0e93 - Browse repository at this point
Copy the full SHA 85f0e93View commit details -
feat(governance): in-runtime policy evaluator + guardrail compensation
Rebase of the guardrail-compensation series onto feat/governance-audit's tip. Brings up the native governance layer in one squash: - In-runtime policy evaluator (native/evaluator.py): rule + check + condition matching with VADER sentiment / chardet / regex / entropy / incident / commitment operators. Honors per-check action overrides and cross-rule aggregation. Instance-scoped with explicit deps (AuditManager + GuardrailCompensator) injected by the host. - Native package exports (native/__init__.py): build_policy_index_from_yaml + GovernanceEvaluator + GuardrailCompensator + CheckContext + PolicyIndex. - GuardrailCompensator (native/guardrail_compensation.py): bounded ThreadPoolExecutor + BoundedSemaphore per runtime, contextvars propagation, weakref-tracked process-level atexit. Delegates HTTP / auth / URL / trace correlation to the injected GovernanceCompensationProvider. - Drop PolicyLoader: host fetches policy asynchronously via GovernancePolicyProvider and hands the resolved PolicyIndex to UiPathGovernedRuntime at construction. - Trace correlation: AuditEvent / AuditRecord no longer carry trace_id; OTel-backed sinks resolve from the live span via the AuditManager's captured contextvars snapshot. - testpypi dev pin (local dev only): uipath-core + uipath-platform pinned to the testpypi dev builds from PR UiPath/uipath-python#1761 (AdapterRegistry deletion + AuditRecord.trace_id field drop) via ``[tool.uv] override-dependencies`` + ``[tool.uv.sources]``. The wheel-baked ``[project.dependencies]`` constraint stays at the canonical ``uipath-core>=0.5.22,<0.6.0`` so consumer workspaces that don't configure testpypi (notably uipath-python's CI matrix) resolve cleanly against published versions. Tests: 346 passed + 1 skipped, ruff + mypy clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for 3b351e0 - Browse repository at this point
Copy the full SHA 3b351e0View commit details -
chore(deps): pin uipath-core + uipath-platform to PR #1761 testpypi dev
Local-only pin (uv-specific tables; not in [project.dependencies], so the published wheel's Requires-Dist is unaffected). Aligns the local resolver with the dev builds from uipath-python PR #1761 (``refactor(core): drop AdapterRegistry + BaseAdapter; keep EvaluatorProtocol``) — those carry the AuditRecord.trace_id field drop the runtime now relies on. - ``override-dependencies`` pins ``uipath-core==0.5.24.dev1017616976`` and ``uipath-platform==0.1.79.dev1017616976`` (the ``uipath`` sub- package block in PR #1761). - ``[tool.uv.sources]`` adds ``uipath-platform = { index = "testpypi" }`` so the platform pin is resolvable; the existing entry for ``uipath-core`` stays put. - ``[tool.uv.exclude-newer-package]`` adds ``uipath-platform = false`` so the 2-day age guard doesn't filter out the dev build (mirrors the existing toggle for ``uipath-core``). The pin will be reverted once PR #1761 lands and a stable ``uipath-core`` is published. Verified: ``uv pip show uipath-core`` → ``0.5.24.dev1017616976``; 346 tests + 1 skipped pass, ruff + mypy clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for fd0529a - Browse repository at this point
Copy the full SHA fd0529aView commit details -
docs(governance): scope evaluator + compensation docstrings to runtim…
…e layer Apply the same docstring-scoping rule as PR #122 to the new evaluator and guardrail-compensation modules. Drop references to the wire-side endpoint (/runtime/govern), to "the governance-server", to "Reinstall uipath-core" in ImportError logs, and to the packs/compile_packs.py sibling tool. Each module now describes only what the runtime layer owns. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 0725a6c - Browse repository at this point
Copy the full SHA 0725a6cView commit details -
docs(governance): clear stale comments after sync-compensator refactor
Sweep across all 17 commits on this branch following Radu's r3492300304 ("outdated comment") review. Fixes: - evaluator: `_dispatch_compensation` docstring still claimed the compensator owned concurrency, queue caps, and process-exit cancellation — all removed in the prior sync-dispatch refactor. - evaluator: `compensator` parameter doc and the inline comment in `evaluate()` referenced `/runtime/govern` and the old fire-and- forget pool semantics. - runtime: module docstring claimed a "thread-pool hop via contextvars.copy_context" — no thread pool to hop anymore. - test_traces_severity: dropped the "§4 of the cross-product unification doc" external-spec citation; kept the verdict-split contract in local terms. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for 6c20235 - Browse repository at this point
Copy the full SHA 6c20235View commit details -
Merge pull request #123 from UiPath/feat/governance-guardrail-compens…
…ation feat(governance): guardrail-fallback compensation
Configuration menu - View commit details
-
Copy full SHA for 6694066 - Browse repository at this point
Copy the full SHA 6694066View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff main...feat/governance-audit