Skip to content

Saved chat, Analyze and orchestration results take their container's access (screening layer 3b) - #1632

Merged
Paul Lizer (paullizer) merged 8 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-screening-layer-3b-chat-orchestration
Oct 3, 2026
Merged

Paul Lizer (paullizer) merged 8 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-screening-layer-3b-chat-orchestration

Conversation

@paullizer

@paullizer Paul Lizer (paullizer) commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Results built from documents are no longer checked against those documents again. Chat AI replies and their stored citations, tool results in history, saved Analyze results, orchestration retained results and files, generated chat files, and conversation and tabular exports now take their access from their conversation or orchestration run. A deleted, re-uploaded or held source document no longer hides them, and chat history no longer replaces a whole AI reply with "Source content is unavailable pending document screening and review."
  • One input check stays. Search retrieval, document selection (including chat uploads), file bytes and previews, opening a cited document, workspace attachments in history, and orchestration or Analyze steps that read documents still need current access, and a held document is refused. The model fence still blocks later model calls after such a read. Container, lineage and integrity checks are unchanged. Nothing is withdrawn after the fact and there's no data migration.
  • A follow-up orchestration step that reads documents named by an earlier run reads their current version instead of failing (functions_orchestration_executor.py). Version checks still protect reads in progress, such as a resumed Analyze checkpoint or a later step in the same attempt.
  • Error messages now name the conversation or saved result instead of source access. New feature doc UPLOAD_ONLY_CONTENT_SCREENING.md explains the whole model.

Stack position: layer 3b, the last open layer of the upload-only screening stack. It targets paullizer-react-v2-ui. Layers 1 and 2 (#1628, #1629), layer 3a (#1631) and Run as (#1630) have already merged there: #1628 landed as c53ef2d and brought in layers 2 and 3a. This branch already contains that content through ad449ae, whose tree is identical to c53ef2d, so the diff is only layer 3b. Version map: Run as is 0.261.229, layers 1 and 2 are 0.261.230, layer 3a is 0.261.231, and this PR is 0.261.232. Merge conflicts were only VERSION (kept 0.261.232), the release-notes order (0.261.232 above 0.261.231, 0.261.230 and 0.261.229), the guide's front-matter version and troubleshooting table, and the history test's header. Layer 1 is relabeled 0.261.230 in UPLOAD_ONLY_CONTENT_SCREENING.md.

Notes for reviewers

  • Cleanup. authorize_analysis_sources stays because input reads still use it: Analyze checkpoints, native analysis, workflow readiness and the orchestration input checks. Its functions_saved_analysis re-export lost its last caller when 3a merged, so this PR removes it (CodeQL flagged the unused import). Rewording AnalysisResultUnavailable is a small follow-up after this PR merges.
  • Renames instead of deletions. OrchestrationResultAccess.authorize_sources became authorize_input_sources, and authorize_orchestration_sources became verify_orchestration_input_sources. They are now used only where a step reads documents itself (the native tabular step and Analyze checkpoints).
  • sanitize_generated_artifact_history is kept in history. It still applies the container checks (conversation participation, approval and publication, workflow scope) and strips private bindings. Its source checks are gone.
  • The publish-time input check is kept. Chat (_persist_screened_assistant) and orchestration delivery (_validate_citations) still re-check the documents that request or run read, so a document held mid-run blocks publishing that run's answer. A newer version of such a document no longer blocks it.
  • Test harness repair. test_analyze_backend_saved_integration.py's harness predated chat content checks and failed on the base. It now passes, 29 of 29.

Linked issue

Refs #1621

Release Notes & Latest Features

  • New Feature
  • Bug Fix
  • UI Enhancement
  • Breaking Change
  • Internal only

Is this visible to end users?

  • Yes
  • No

Is this admin-facing (Admin Settings, governance, deployment, config)?

  • Yes
  • No

Should this become a Latest Feature card?

  • Yes
  • No
  • Already added

Screenshot needed for the card?

  • Yes
  • No
  • Attached

Version bump

  • application/single_app/config.py VERSION third segment bumped, or not needed because this is docs-only (0.261.232)
  • deployers/version.txt bumped, or not needed because deployers/ was not changed

Testing / validation

New test (proving the fix):

  • python -m pytest functional_tests\test_saved_results_container_access_chat_orchestration.py -q passed: 23 tests, 6 subtests.
  • The same test with the application/single_app changes stashed: 25 failed, 4 passed. The test detects the old behavior.

Regression groups. FAILED/ERROR sets are compared with a baseline taken at 66a29bd before editing, using the same runner and mode. No group has new failures.

  • Core group: baseline 53, after 35, 0 new. It covers test_analysis_*.py, test_analyze_*.py, test_content_screening_*.py, test_generated_*.py, test_*conversation*export*.py and the three route policy tests.
  • Related group: baseline 90, after 86, 0 new. It covers test_saved_analysis_*, test_document_analysis_*, test_document_provenance_*, test_chat_artifact_*, test_*publication*, test_tabular_*generated*, test_mixed_source_*, test_enhanced_citations_*, test_*citation*, test_*history* and test_group_screening_*.
  • test_orchestration_[a-k]*.py, run per file with PYTHONPATH: baseline 2, after 0, 0 new.
  • test_orchestration_[l-r]*.py: baseline 56, after 53, 0 new.
  • test_orchestration_[s-z]*.py: baseline 10, after 3, 0 new.
  • Workflow group: baseline 91, after 88, 0 new. It covers test_workflow_*.py, test_group_workflow_*.py and route_tests\test_workflow_*_policy.py.
  • The first pass flagged two kinds of failures. Some were source re-check tests, which this PR rewrites. The others were cold-import probes that timed out on the shared, heavily loaded machine. All 35 affected files were re-run after the rewrites, with 0 failures.

Route policy:

  • python -m pytest functional_tests\route_tests\test_route_blueprint_policy_inventory.py passed: 11 tests.
  • python -m pytest functional_tests\route_tests\test_route_unauthenticated_policy_contract.py passed: 6 tests.
  • python -m pytest functional_tests\route_tests\test_route_policy_test_coverage.py passed: 2 tests.

V2 UI (application\v2_ui, with local Playwright and PLAYWRIGHT_SERVICE_URL unset):

  • npm run typecheck passed.
  • npm --prefix .\application\v2_ui run build -- --outDir ..\..\ui_tests\artifacts\orchestration-plan-editor passed.
  • python -m pytest ui_tests\test_v2_orchestration_*.py: 33 failed, 297 passed, 49 errors. The baseline was 33 failed, 295 passed, 49 errors, so there are 0 new failures. All tests in test_v2_orchestration_outputs.py pass.

Docs:

  • python scripts\build_docs_inventory.py: line-ending change only, reverted.
  • python functional_tests\test_docs_app_surface_coverage.py: 7/7 passed.
  • python functional_tests\test_docs_site_quality.py: 6/6 passed.

Guardrails (<files> is the 58 changed files):

  • python scripts\check_xss_sinks.py --base-sha 66a29bd60 --head-sha HEAD <files> passed for 49 files.
  • python scripts\check_broken_access_control.py --base-sha 66a29bd60 --head-sha HEAD <files> passed for 48 files.
  • python scripts\check_swagger_routes.py application/single_app/route_backend_chats.py application/single_app/route_enhanced_citations.py passed.
  • git diff --check 66a29bd60 HEAD is clean.

After merging the updated base (ad449ae, with #1629, #1631 and #1630):

  • Focused per-file run of 153 files on the layer 2 + 3a merge: every failure is either in the original baseline or fails the same way on the base. Two files timed out under machine load; on a re-run, test_analyze_live_write_fences.py passed 18 of 18 and test_group_document_count_predicate.py passed 9 of 9. The 153 files are the core and related patterns, test_group_document_*, test_public_document_*, test_orchestration_output_*, test_orchestration_render_*, and every test file changed by layers 2, 3a and 3b.
  • 27 suspect and base-delta files run on both the merged HEAD and an export of the base: base 59 failures, HEAD 56, 0 new.
  • On the final HEAD, the new test passed 23 tests and 6 subtests. Also passing: test_content_screening_history.py (11), test_saved_analysis_service.py (15), test_analyze_backend_saved_integration.py (29), and the three route policy tests (11, 6 and 2).
  • npm run typecheck and the V2 build passed. python -m pytest ui_tests/test_v2_orchestration_outputs.py ui_tests/test_v2_orchestration_workflow_proposal_card.py passed 98 tests.
  • Docs inventory: line-ending change only, reverted. test_docs_app_surface_coverage.py passed 7/7 and test_docs_site_quality.py passed 6/6. XSS, broken-access-control and swagger guardrails pass against the new base, and git diff --check is clean.
  • The PR now targets paullizer-react-v2-ui at c53ef2d. Its tree is identical to ad449ae, so these results apply unchanged.
  • CodeQL follow-up (7c7f75c): removed the unused re-export and replaced an empty except in the new test with assertRaises. The new test, the saved-analysis and Analyze integration tests, test_workflow_structured_publication.py, test_content_screening_history.py, the blueprint route inventory and the docs checks pass, 14 files in all; pyflakes is clean.

Documentation

  • Release notes updated, or not needed
  • Feature documentation updated, or not needed
  • Fix documentation updated, or not needed

Release notes: ### **(v0.261.232)**, under Breaking Changes. Feature documentation:

  • New: UPLOAD_ONLY_CONTENT_SCREENING.md.
  • Updated: CONTENT_SCREENING_FRAMEWORK.md (scope rewritten; "Retained-result authority failures" removed and replaced with "Input reads and the model fence"; 3a's fence paragraph kept verbatim), ANALYZE_RESULTS.md, ORCHESTRATION_OUTPUT_LIFECYCLE.md, ORCHESTRATION_CHECKPOINT_RECOVERY.md, DOCUMENT_PROVENANCE.md, guides/review-screened-documents.md and guides/analyze-results.md.
  • No fix doc is needed.

Security checklist

  • New Flask routes include @swagger_route(security=get_auth_security())
  • Settings sent to non-admin frontends use sanitize_settings_for_user()
  • Browser JavaScript is served from local SimpleChat static assets only; no CDN-hosted JS
  • No secrets, keys, connection strings, or local-only artifacts are included

This PR adds no routes, settings payloads or browser assets.

Paul Lizer (paullizer) and others added 2 commits October 3, 2026 03:08
…access

Layer 3b of the upload-only content screening stack (Refs microsoft#1621). Results built
from documents are no longer checked against those documents again. Chat AI
replies and their stored citations, tool results in history, saved Analyze
results, orchestration retained results and files, generated chat files and
conversation and tabular exports take their access from their conversation or
orchestration run, so a deleted, re-uploaded or held source no longer hides them.

The one input check stays: search retrieval, document selection, file bytes and
previews, opening a cited document, workspace attachments in chat history and
orchestration or Analyze steps that read documents still need current access,
and a held document is refused. The model fence still blocks later model calls
after such a read. Container, lineage and integrity checks are unchanged.

- content_screening/access.py: public_history_messages never replaces assistant
  or tool content or stored citations; only workspace attachments are refreshed.
- functions_saved_analysis.py: save and read paths check the container and
  lineage only; recorded sources are provenance.
- functions_orchestration_results.py / _source_access.py: retained results check
  the producer, conversation and run only; authorize_sources and
  authorize_orchestration_sources become input-only authorize_input_sources and
  verify_orchestration_input_sources.
- functions_orchestration_executor.py: sources named by an earlier run or attempt
  are read at their current version after the input check.
- route_backend_chats.py, route_enhanced_citations.py,
  functions_tabular_generated_exports.py: model history, chat artifact downloads
  and completed exports no longer re-check sources.
- New functional test test_saved_results_container_access_chat_orchestration.py;
  source re-check tests rewritten to keep their container, integrity and input
  cases. New feature doc UPLOAD_ONLY_CONTENT_SCREENING.md; related docs updated.
- VERSION 0.261.232 and release notes (Breaking Changes).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Leave the framework's documentation-version line and existing coverage
paragraph intact for layer 2 (microsoft#1629), and add the 0.261.232 notes beside them.
Fold the guide's new scope sentence into its own section.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) and others added 4 commits October 3, 2026 12:32
Bring in the upload-only intake changes that merged into
paullizer-workspace-knowledge-holds. Conflict resolution:
- config.py: keep VERSION 0.261.232.
- release_notes.md: keep the 0.261.232 section above 0.261.230.
- review-screened-documents.md: keep version 0.261.232 and layer 2's two new
  troubleshooting rows, with the workspace-attachment row from 3b.
- test_content_screening_history.py: Version 0.261.232 with both notes.
- CONTENT_SCREENING_FRAMEWORK.md: scope and documentation-version lines now
  credit 0.261.230 for intake and 0.261.232 for container access.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bring in the workflow saved-result changes that merged into
paullizer-workspace-knowledge-holds. Conflict resolution:
- config.py: keep VERSION 0.261.232.
- release_notes.md: keep the 0.261.232 section above 0.261.231 and 0.261.230.
CONTENT_SCREENING_FRAMEWORK.md, content_screening/access.py and
functions_saved_analysis.py merged cleanly; 3a's fence paragraph, fence helper
and workflow-only saved-analysis lines are unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bring in the base branch update that released Run as (microsoft#1630) as 0.261.229 and
relabeled layer 1 as 0.261.230. The merge was clean: VERSION stays 0.261.232
and the release notes run 0.261.232, 0.261.231, 0.261.230, 0.261.229.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Run as (microsoft#1630) shipped as 0.261.229, so layers 1 and 2 ship together as
0.261.230. Link the merged 3a and 3b pull requests in the delivery table.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) changed the base branch from paullizer-workspace-knowledge-holds to paullizer-react-v2-ui October 3, 2026 17:57
microsoft#1628 merged layer 1's branch, with layers 2 and 3a, into paullizer-react-v2-ui,
so the delivery section no longer says every layer targets layer 1's branch.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread application/single_app/functions_saved_analysis.py Fixed
functions_saved_analysis no longer re-exports authorize_analysis_sources; layer 3a
removed its last caller. The headless fence test catches the refused input read
with assertRaises instead of an empty except, which also checks the read failed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit e1e6949 into microsoft:paullizer-react-v2-ui Oct 3, 2026
11 checks passed
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 3, 2026
The target branch took 0.261.232 for #1632, where saved chat, Analyze and
orchestration results take their container's access. Keep its release notes
entry, move this fix to a new 0.261.233 section, and renumber the fix
document, the logging reference note and the test headers.

#1632 also changed what output_access_denied means: its message now says
access to the file's conversation could not be confirmed, and a changed
source no longer fails a retained file. The PermissionError classification
is unchanged. Reword this fix's notes, which called the code a source-access
refusal, to call it an access refusal.

Refs #1623

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) deleted the paullizer-screening-layer-3b-chat-orchestration branch October 3, 2026 18:51
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 3, 2026
… Run as

The microsoft#1621 screening changes (microsoft#1628, microsoft#1631, microsoft#1632) and microsoft#1630 have landed on
paullizer-react-v2-ui, so the roadmap no longer describes V2 where it says a
result is withheld when a source document becomes unreadable, or that every
material edit needs Run as approval again.

- §7: reads and deliveries re-check the chat, workflow and run that hold a
  result; since 0.261.231 the documents a run's tasks read are provenance only.
- Gotcha 36: delivery no longer withholds a result over an unreadable source.
- 6a: "lost access" in its Done when now means access to the workflow or run.
- Gotchas 4 and 15: since 0.261.229 a revision the Run as user saved, assistant
  edits included, runs as them without a separate approval; changes saved by
  someone else still ask again.
- The intro names both changes.

Docs only; the original plan text in §5 and the shipped Phase 3 notes are left
as history.

Refs microsoft#1543 microsoft#1546 microsoft#1621

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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