Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: UiPath/uipath-runtime-python
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: UiPath/uipath-runtime-python
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feat/governance-audit
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 19 commits
  • 23 files changed
  • 4 contributors

Commits on Jun 27, 2026

  1. feat(governance): enforcement-mode config, policy models, deps

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    79fd38f View commit details
    Browse the repository at this point in the history
  2. 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>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    bb77290 View commit details
    Browse the repository at this point in the history
  3. 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>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    319c5fb View commit details
    Browse the repository at this point in the history
  4. 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>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    2a34075 View commit details
    Browse the repository at this point in the history
  5. feat(governance): policy backend client, YAML compiler, loader

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    f05dfaf View commit details
    Browse the repository at this point in the history
  6. 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>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    87c4f21 View commit details
    Browse the repository at this point in the history
  7. 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>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    297193e View commit details
    Browse the repository at this point in the history
  8. 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>
    2 people authored and viswa-uipath committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    4000928 View commit details
    Browse the repository at this point in the history
  9. 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>
    viswa-uipath and claude committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    be6e666 View commit details
    Browse the repository at this point in the history
  10. 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>
    viswa-uipath and claude committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    62e8612 View commit details
    Browse the repository at this point in the history
  11. 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>
    viswa-uipath and claude committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    13cd366 View commit details
    Browse the repository at this point in the history
  12. 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>
    3 people committed Jun 27, 2026
    Configuration menu
    Copy the full SHA
    7e4ef8d View commit details
    Browse the repository at this point in the history

Commits on Jun 29, 2026

  1. 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>
    viswa-uipath and claude committed Jun 29, 2026
    Configuration menu
    Copy the full SHA
    c4e7958 View commit details
    Browse the repository at this point in the history
  2. 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>
    viswa-uipath and claude committed Jun 29, 2026
    Configuration menu
    Copy the full SHA
    85f0e93 View commit details
    Browse the repository at this point in the history
  3. 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>
    viswa-uipath and claude committed Jun 29, 2026
    Configuration menu
    Copy the full SHA
    3b351e0 View commit details
    Browse the repository at this point in the history
  4. 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>
    viswa-uipath and claude committed Jun 29, 2026
    Configuration menu
    Copy the full SHA
    fd0529a View commit details
    Browse the repository at this point in the history
  5. 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>
    viswa-uipath and claude committed Jun 29, 2026
    Configuration menu
    Copy the full SHA
    0725a6c View commit details
    Browse the repository at this point in the history
  6. 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>
    viswa-uipath and claude committed Jun 29, 2026
    Configuration menu
    Copy the full SHA
    6c20235 View commit details
    Browse the repository at this point in the history
  7. Merge pull request #123 from UiPath/feat/governance-guardrail-compens…

    …ation
    
    feat(governance): guardrail-fallback compensation
    viswa-uipath authored Jun 29, 2026
    Configuration menu
    Copy the full SHA
    6694066 View commit details
    Browse the repository at this point in the history
Loading