Skip to content

Forward-merge release/2.2 into develop - #364

Merged
GPUtester merged 1 commit into
developfrom
release/2.2
Jul 17, 2026
Merged

Forward-merge release/2.2 into develop#364
GPUtester merged 1 commit into
developfrom
release/2.2

Conversation

@rapids-bot

@rapids-bot rapids-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

Forward-merge triggered by push to release/2.2 that creates a PR to keep develop up-to-date. If this PR is unable to be immediately merged due to conflicts, it will remain open for the team to manually merge. See forward-merger docs for more info.

#### Overview

Restores supported PII masking in the AI-Q 2.2 release image and makes output guardrail failures fail closed instead of escaping as generic internal errors.

The release runtime previously included NeMo Guardrails without the Presidio, spaCy, and language-model dependencies required by `sensitive_data_detection`. Because those imports are lazy, the service could start healthy but fail every response once output PII masking ran. Output-rail exceptions could also escape the middleware boundary.

#### What changed

- Add a dedicated `pii` runtime extra containing the NAT Security defense dependencies and pinned `en-core-web-lg==3.8.0` model.
- Install the `pii` extra in the release image and execute the public NeMo `mask_sensitive_data` action during the Docker build.
- Contain output-rail binding, traversal, evaluation, rewriting, and terminal-synchronization failures at the shared middleware boundary.
- Return traversal-independent, schema-compatible emergency refusals for workflow, shallow-agent, and deep-agent outputs.
- Sanitize guardrail exception logs so they include safe boundary context and exception type without arbitrary exception text or protected output.
- Buffer and guard string, structured, and mixed string/structured streams as one logical output before emission.
- Synchronize every rewritten structured chunk's `workflow_outcome.result` so later chunks cannot retain unfiltered content.
- Keep workflow-specific terminal synchronization in the workflow middleware rather than the generic guardrails mixin.
- Keep immutable application assets root-owned while making `/app/data` writable by runtime UID 1000.
- Document stream behavior and the optional PII runtime dependency contract.

#### DCO sign-off for the squash commit

Signed-off-by: Tanner Leach <tleach@nvidia.com>

#### Validation

- [x] `uv run ruff check .`
- [x] `uv run ruff format --check .` — 370 files
- [x] `uv run pytest -q tests/aiq_agent/guardrails` — 99 passed
- [x] `uv run pytest -q` — 1788 passed, 13 skipped
- [x] `uv run nat --help` and `uv run aiq-research --help`
- [x] Sphinx documentation build with warnings treated as errors
- [x] Release Docker build
- [x] In-image public NeMo `mask_sensitive_data` action returned `Contact <EMAIL_ADDRESS>`
- [x] Runtime UID 1000 could read/execute application assets and create/read/delete data under `/app/data`
- [x] Local release-equivalent deployment returned HTTP 200 for health and chat
- [x] Benign output passed unchanged in both the public choice and terminal workflow outcome
- [x] Email output was masked in both fields; the serialized response contained no raw email
- [x] Forced rail failures returned boundary-compatible refusals in deterministic regular and streaming tests
- [x] Captured middleware exception logs excluded protected output and internal exception messages
- [x] Commits are GPG-signed and DCO-signed as `Tanner Leach <tleach@nvidia.com>`
- [x] Documentation updated for user-facing behavior and installation requirements
- [x] Confirmed the PR contains no secrets or credentials

Formal QA cases `26.07_GUARD_001` and `26.07_GUARD_002` remain to be run against a published corrected image.

#### Where should reviewers start?

1. `src/aiq_agent/guardrails/interface/middleware.py` — shared exception containment and buffered stream handling.
2. `src/aiq_agent/guardrails/workflow/middleware.py` — workflow-shaped emergency refusals and terminal-outcome synchronization.
3. `tests/aiq_agent/guardrails/test_workflow_guardrails.py` — multi-chunk, mixed-order stream, synchronization-failure, no-target, and PII-safe logging regressions.
4. `pyproject.toml` and `deploy/Dockerfile` — PII extra and release-image verification.

#### Related Issues

- Relates to AIQ-3572 / NVBug 6454040



## Summary by CodeRabbit

* **New Features**
  * Added an optional PII dependency bundle (Presidio defense) with a compatible spaCy model.
  * Improved guardrails to emit schema-safe emergency refusal states during blocked/error scenarios.
* **Bug Fixes**
  * Prevent sensitive/unfiltered content from being returned when input/output guardrails evaluation fails.
  * Improved workflow and streaming output sanitization, including synchronization across mixed text and structured responses.
* **Documentation**
  * Expanded guardrails failure behavior and PII runtime requirements.
* **Tests**
  * Added/extended coverage for deep, shallow, and workflow guardrails refusal and masking paths.

Authors:
  - Tanner Leach (https://github.com/tanleach)

Approvers:
  - Eric Evans II (https://github.com/ericevans-nv)
  - Kyle Zheng (https://github.com/KyleZheng1284)

URL: #358
@rapids-bot
rapids-bot Bot requested a review from a team July 17, 2026 20:24
@GPUtester
GPUtester merged commit 7eda0d7 into develop Jul 17, 2026
@rapids-bot

rapids-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown
Author

SUCCESS - forward-merge complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants