Skip to content

Commit f1a607b

Browse files
aditik0303claude
andcommitted
feat(governance): GovernanceRuntime wrapper + runtime registry wiring
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent aeb0d94 commit f1a607b

9 files changed

Lines changed: 2093 additions & 24 deletions

File tree

docs/runtime-wrapper-extension.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Governance Integration Point
2+
3+
`uipath-runtime` wraps runtimes with governance via a single direct
4+
function, `apply_governance_wrapper`, gated by the
5+
`EnablePythonGovernanceChecker` feature flag.
6+
7+
Governance contracts (feature-flag, exceptions, models) live in
8+
`uipath.core.governance` (in `uipath-core`); the runtime-side wrapper
9+
lives here in `uipath.runtime.governance`. Runtime has **no separate
10+
`uipath-governance` dependency** — the contracts namespace is always
11+
available because `uipath-core` is already a hard dep. When the flag
12+
is off, `uipath.runtime.governance.wrapper` is **not imported** — its
13+
transitive cost stays off the startup path.
14+
15+
## How it works
16+
17+
```
18+
UiPathRuntimeFactoryRegistry.get(...)
19+
↓ returns
20+
UiPathWrappedRuntimeFactory.new_runtime(...)
21+
↓ calls
22+
apply_governance_wrapper(runtime, context, runtime_id)
23+
24+
if _is_governance_enabled():
25+
from uipath.runtime.governance.wrapper import governance_wrapper # lazy
26+
return governance_wrapper(runtime, context, runtime_id)
27+
else:
28+
return runtime # unwrapped, no governance import
29+
```
30+
31+
## Feature flag
32+
33+
| Setting | Effect |
34+
|---|---|
35+
| `FeatureFlags.configure_flags({"EnablePythonGovernanceChecker": True})` (typically via gitops) | Governance is applied |
36+
| `UIPATH_FEATURE_EnablePythonGovernanceChecker=true` env var | Governance is applied (fallback when no programmatic config) |
37+
| Neither set | Governance **not** applied; `uipath.runtime.governance.wrapper` is **not imported** |
38+
39+
Resolution and fallback semantics come from `uipath-core`'s
40+
`FeatureFlags.is_flag_enabled(..., default=False)`. Programmatic
41+
configuration beats env var.
42+
43+
## API
44+
45+
```python
46+
from uipath.runtime import (
47+
GOVERNANCE_FEATURE_FLAG, # "EnablePythonGovernanceChecker"
48+
apply_governance_wrapper, # the call-site
49+
)
50+
```
51+
52+
`apply_governance_wrapper(runtime, context, runtime_id)` is an
53+
`async` function. It returns the original runtime untouched when the
54+
flag is off or when the wrapper itself raises — governance failures
55+
must never break agent execution.
56+
57+
## Why deferred-import matters
58+
59+
When the flag is off, `apply_governance_wrapper` returns before the
60+
`from uipath.runtime.governance.wrapper import governance_wrapper` line
61+
ever runs. That keeps governance's transitive imports — audit,
62+
evaluator, OpenTelemetry, the policy index — entirely off the startup
63+
hot path.
64+
65+
## Testing
66+
67+
Force the flag on/off per test via `FeatureFlags`:
68+
69+
```python
70+
from uipath.core.feature_flags import FeatureFlags
71+
from uipath.runtime.wrapper import GOVERNANCE_FEATURE_FLAG
72+
73+
# Force enable
74+
FeatureFlags.configure_flags({GOVERNANCE_FEATURE_FLAG: True})
75+
76+
# Force disable
77+
FeatureFlags.configure_flags({GOVERNANCE_FEATURE_FLAG: False})
78+
79+
# Reset (typically in a teardown fixture)
80+
FeatureFlags.reset_flags()
81+
```
82+
83+
Use `sys.modules` patching to stub `uipath.runtime.governance.wrapper`
84+
when you need to assert against the wrapper invocation without
85+
actually importing it — see `tests/test_wrapper.py` for the fixture.

src/uipath/runtime/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
)
4444
from uipath.runtime.schema import UiPathRuntimeSchema
4545
from uipath.runtime.storage import UiPathRuntimeStorageProtocol
46+
from uipath.runtime.wrapper import (
47+
GOVERNANCE_FEATURE_FLAG,
48+
apply_governance_wrapper,
49+
)
4650

4751
__all__ = [
4852
"UiPathExecuteOptions",
@@ -73,4 +77,7 @@
7377
"UiPathResumeTriggerName",
7478
"UiPathChatProtocol",
7579
"UiPathChatRuntime",
80+
# Governance integration (direct, FF-gated, lazy import)
81+
"GOVERNANCE_FEATURE_FLAG",
82+
"apply_governance_wrapper",
7683
]

0 commit comments

Comments
 (0)