You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Addresses all 7 Copilot review comments on PR #118 and switches the
default enforcement mode so empty-policy tenants pay zero per-call
audit overhead.
PR-118 review comments:
- policy_api_client docstring no longer claims "one retry on transient
failures" — _get_once is and remains single-shot by design.
- Policy fetch GET drops Content-Type: application/json (was sent via
json_body=True). Strict origin servers can 415 on unexpected
Content-Type for GETs; the helper's own docstring recommends
omitting it on reads.
- _extract_governable_text dumper loop now CONTINUES instead of BREAKS
when model_dump() raises, so dict() is tried as documented ("fall
through to other extractors").
- loader.get_policy_index distinguishes "prefetch did not complete in
Xs" from "prefetch completed but produced no PolicyIndex" — prod
triage can now tell a hung fetch from an auth / parse failure.
- disabled_guardrails defensively re-checks mapped_to_uipath=True AND
policy_enabled=False on every guardrail_fallback condition. Matches
the function's docstring and protects against multi-condition rules
or any future code path that bypasses the evaluator gate.
- request_governance pre-checks UIPATH_ACCESS_TOKEN and skips when
missing. Sending without a bearer guarantees a 401 per compensation
call and pollutes logs; mirrors the org-id / tenant-id skip pattern
already in place.
- AuditManager.flush(timeout=...) now honors its timeout via a
time.monotonic() poll loop and warns if drain doesn't complete.
Previously called queue.Queue.join() with no timeout argument,
allowing indefinite block — risky at process exit where
_cleanup_audit_manager supplies a 2-second timeout that was being
silently ignored.
Default enforcement mode:
- get_enforcement_mode default fallback flipped from AUDIT to
DISABLED. The server-supplied mode (applied by the policy loader on
every successful fetch) still wins; the env-var override still
works. Empty-policy / failed-fetch / pre-fetch tenants now
short-circuit at evaluator.py:332 with no _emit_audit call, no OTel
spans, no AuditManager queue traffic. Previously these scenarios
silently fell through to AUDIT and produced ~40 empty governance
spans per turn for an N=10 LLM-call agent.
Tests (245 passing, +7 new):
- test_enforcement_mode_default.py pins the resolution order
(programmatic > env > DISABLED default) and the
invalid-env-falls-back-to-DISABLED behavior.
- test_request_governance_skipped_when_token_missing pins the new
bearer-token skip path.
- _govern_env fixture now sets UIPATH_ACCESS_TOKEN; the headers test
asserts the Authorization header is present (was a side-effect of
the no-token test, which is now moved out).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments