Commit 470533e
refactor(governance): instance-scope GuardrailCompensator + trace_id from wiring
Addresses radu's recurring PR #121 patterns applied to the guardrail
compensation slice. Resolves the post-PR-#121 ImportError in the test
file (it referenced the deleted ``uipath.runtime.governance.config`` /
``tests._helpers.reset_enforcement_mode``).
Architectural — match the AuditManager / PolicyLoader shape
- New GuardrailCompensator class. Each GovernanceRuntime instance gets
one — owns its own ThreadPoolExecutor, BoundedSemaphore, and provider.
uipath eval parallel runtimes no longer share workers, queue slots,
or saturation state.
- Module globals _pool / _inflight / _INFLIGHT_CAP / @atexit.register
decorator removed. Process cleanup via a weakref.WeakSet of live
compensators + one process-level atexit hook (same pattern PR #122
introduced for AuditManager): N runtimes → 1 atexit slot, no strong
ref pinning disposed compensators.
- close() is an instance method, idempotent, logs at debug on failure.
- The free submit_compensation function is gone — callers use
compensator.submit(...).
Boundary — env reads move to the wiring layer
- _resolve_trace_id signature changed to (supplied, fallback). It no
longer reads UIPATH_TRACE_ID. The runtime layer is now env-free for
this code path.
- GovernanceRuntime accepts a trace_id: str | None constructor arg and
exposes it via the .trace_id property. The wiring layer (uipath CLI)
reads UIPATH_TRACE_ID and passes the value in; the evaluator slice
forwards it into GuardrailCompensator(provider, trace_id=...).
- GuardrailCompensator accepts trace_id at construction; it becomes
the authoritative source. Per-submit trace_id is a per-call fallback.
Polish
- Replaced bare except Exception: pass in _resolve_trace_id with a
logger.debug (bandit B110 cleared on this file).
- Removed ENV_TRACE_ID constant + the os import that backed it.
Tests
- Full rewrite of test_guardrail_compensation to drop deleted imports
(config, reset_enforcement_mode), use GuardrailCompensator(provider),
and mirror AuditManager's lifecycle test set (one atexit
registration, weakref GC, idempotent close, cross-instance
isolation, semaphore release on provider error).
- New test_resolve_trace_id_does_not_read_env pins the boundary rule:
even with UIPATH_TRACE_ID set, the runtime layer ignores it.
- New test_compensator_trace_id_overrides_caller_supplied_value pins
the construction-supplied value winning over per-submit.
- New test_governance_runtime_stashes_trace_id +
test_governance_runtime_default_trace_id_is_none cover the new
GovernanceRuntime kwarg + property.
238 passed, ruff/mypy clean; bandit clean on the touched files (one
pre-existing B101 in _yaml_to_index.py is unchanged and out of scope).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent cdbae81 commit 470533e
4 files changed
Lines changed: 484 additions & 407 deletions
File tree
- src/uipath/runtime/governance
- native
- tests
0 commit comments