Skip to content

Stop re-checking workflow run sources in run history and after a task saves - #1628

Merged
Paul Lizer (paullizer) merged 14 commits into
paullizer-react-v2-uifrom
paullizer-workspace-knowledge-holds
Oct 3, 2026
Merged

Paul Lizer (paullizer) merged 14 commits into
paullizer-react-v2-uifrom
paullizer-workspace-knowledge-holds

Conversation

@paullizer

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

Copy link
Copy Markdown
Contributor

Summary

Layer 1 of 4 for #1621: content screening checks uploaded documents, and anything generated from them takes its access from the workflow, run or conversation it belongs to.

  • Run history loads again. Run lists, run task items, the live run activity view and the last-run preview in the workflow list no longer re-check each run's source documents. Before, one run that used a document later deleted or re-uploaded turned the whole list into a 403: "Run history is unavailable because source access could not be confirmed."
  • Tasks stop failing after saving output. The runner no longer reads each task's output back through the source check right after saving it, which failed the task with "Saved task output was withheld because its source access could not be confirmed." Reading a previous task's output as an input is unchanged.
  • Container checks are unchanged. The workflow must still be in your scope, group routes still require membership, and a run from another workflow still answers 404.
  • Approvals page. The content screening notice appears only while screening is enabled, with plain wording. Each screening request keeps its own Open content review link.

Still re-checked until layer 3: per-task previews inside run history (sanitize_workflow_analysis_history) and structured execution history.

Linked issue

Fixes #1613
Refs #1621

Related PRs and merge order

PR What it does Base
#1629 Layer 2: only user uploads and File Sync are screened this branch
#1631 Layer 3a: saved workflow results take their access from the workflow and run this branch
#1632 Layer 3b: saved chat, Analyze and orchestration results take their access from their container this branch
#1630 Run as asks for approval only when someone else authored the revision or the connection changes paullizer-react-v2-ui
  1. Merge this PR first, with a merge commit rather than a squash. The three layer PRs contain this branch's commits, so after a squash their diffs would show these changes again.
  2. Merge Limit content screening intake to uploads and apply metadata edits directly (layer 2 of 4) #1629, Stop re-checking saved workflow results against their source documents (screening layer 3a) #1631 and Saved chat, Analyze and orchestration results take their container's access (screening layer 3b) #1632 after it. Write access lapsed partway through, so they were opened from the paullizer/simplechat fork. GitHub stacks don't support fork heads, so they target this branch directly instead.
  3. Ask for M365 Run as approval only when someone else authored the revision #1630 is independent and can merge at any point.

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

Testing / validation

These commands ran in a session virtual environment layered on the global Python. The overlay adds cryptography 46.0.7 and the app's pinned Flask 3.1.3 / Werkzeug 3.1.6, because the global Flask 2.2.5 with Werkzeug 3.1.4, and cryptography 50 with pyOpenSSL 25.3, break test collection.

  • New and updated tests: python -m pytest functional_tests/test_workflow_run_history_source_recheck_fix.py functional_tests/test_workflow_history_source_access.py -q passed (16 passed), both before and after merging the base branch. With the route, runner and template changes stashed, 8 of the 11 tests in the new file fail. The 3 that still pass are the version check and the container 404 checks.
  • Regression comparison, before and after on the same 29 files: no new failures, and 2 previously failing tests fixed.
    • Files: workflow runner, result, route, provenance and analysis-publication test files, including test_workflow_task_sequence.py, test_workflow_structured_flow.py, test_workflow_result_routes.py, test_workflow_durable_routes.py and test_document_provenance_origin.py.
    • The remaining failures also fail on the base branch. Most come from stale harnesses: one patches the removed functions_workflow_context.resolve_model_token_limits, another can't import the new functions_workflow_chat_delivery. The rest need Azure configuration.
  • Integration with the other layers: all five PRs were merged into a local, unpushed tree. That tree, this branch alone and the base branch (fd842e199) were compared across the functional suite (details on #1621).
    • In a normal run, this branch fails exactly the same tests as the base branch.
    • One test changes outcome here, but only once its out-of-date setup is filled in. test_native_source_revocation_blocks_saved_report_and_publication normally errors at setup on the base branch too.
    • With the setup filled in, a revoked source is now refused one step later, with "A required source is no longer available for this workflow run.", so the test's message pattern no longer matches. Stop re-checking saved workflow results against their source documents (screening layer 3a) #1631 inverts the test for the final design.
  • Classic screening UI suite: python -m pytest ui_tests/test_content_screening_classic.py (local Chromium) gave 46 passed, 3 failed.
    • The new test_classic_approvals_screening_notice_follows_the_screening_setting[True/False] passes. After the merge, the approvals subset (-k approval) passed 11/11.
    • The 3 failures are test_classic_policy_prerequisites_fail_closed and test_classic_disable_new_scans_preserves_review_holds[True/False]. They fail identically on the base branch, because the configuration save payload now includes workspace_uploads_enabled.
    • The fixture now answers the Approvals page's /api/m365/requests and /api/msgraph/pending-actions calls. Without that, every approvals test in this suite errored at teardown on the base branch too.
  • Route policy tests, all passed:
    • python functional_tests/route_tests/test_route_blueprint_policy_inventory.py (11/11)
    • python functional_tests/route_tests/test_route_unauthenticated_policy_contract.py (6/6)
    • python functional_tests/route_tests/test_route_policy_test_coverage.py (2/2)
  • Docs:
    • python scripts/build_docs_inventory.py regenerated the inventory with no content change.
    • python functional_tests/test_docs_app_surface_coverage.py passed (7/7).
    • python functional_tests/test_docs_site_quality.py passed (6/6).
  • PR guardrails, all passed:
    • python scripts/check_xss_sinks.py --base-sha <base> --head-sha <head> <changed files>
    • python scripts/check_broken_access_control.py --base-sha <base> --head-sha <head> <changed files>
    • python scripts/check_swagger_routes.py application/single_app/route_backend_workflows.py
  • Whitespace: git diff --check is clean.

Documentation

  • Release notes updated (v0.261.229: Bug Fixes and User Interface Enhancements)
  • Feature documentation not needed for this layer; the screening framework docs are rewritten in layer 3
  • Fix documentation updated (docs/explanation/fixes/WORKFLOW_RUN_HISTORY_SOURCE_RECHECK_FIX.md); docs/guides/review-approval-requests.md also notes the notice

Security checklist

  • New Flask routes include @swagger_route(security=get_auth_security()) (no new routes; existing decorators unchanged)
  • Settings sent to non-admin frontends use sanitize_settings_for_user() (the Approvals page already renders sanitized settings, which keep enable_content_screening)
  • Browser JavaScript is served from local SimpleChat static assets only; no CDN-hosted JS (no JavaScript changes)
  • No secrets, keys, connection strings, or local-only artifacts are included

Paul Lizer (paullizer) and others added 5 commits October 2, 2026 22:04
… saves

Workflow run lists, run task items, the live run activity view and the
workflow list's last-run preview re-authorized every saved result against
the current state of its source documents. One run that used a document
later deleted or re-uploaded turned the whole run list into a 403
("Run history is unavailable because source access could not be
confirmed."). The runner also read each task's output back through the same
check right after saving it and failed the task when that read-back raised.

Runs now take their access from the workflow they belong to. The existing
container checks stay: the workflow must be in the caller's scope, group
routes still require membership, and a run from another workflow still
answers 404. Reading a previous task's output as an input is unchanged.

The Approvals page's content screening notice now renders only while
content screening is enabled and uses plain wording. Each screening request
keeps its own Open content review link, so earlier holds stay reachable.

This is the first layer of limiting content screening to uploaded
documents. Version 0.261.228.

Fixes #1613
Refs #1621

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…261.229

The base branch took 0.261.228 for the V2 workflow alert Open button, so
this layer moves to 0.261.229. Its release notes sit above the base
branch's 0.261.228 entry.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The base branch took 0.261.228, so the fix documentation, guide note and
test version headers now name 0.261.229.

Refs #1621

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…rectly

Layer 2 of 4 for #1621, stacked on #1628.

- Mark documents SimpleChat generates (agent uploads and published artifacts)
  with a server-managed screening_exemption field set in create_document before
  the initial screening marker is chosen. Exempt documents without a marker are
  never enrolled, prepared, scanned or picked up by scan jobs. User uploads,
  chat uploads saved to a workspace and File Sync are still screened.
- Remove the publication screening reservation and its consume latch. Approval
  admits a destination without a screening marker or with an available release.
- Apply metadata edits and model-generated metadata directly instead of queueing
  a metadata rescan, keep the source-format rename rule, stop comparing the
  metadata fingerprint in release proof and recovery, and stop rewriting a
  screened release blob's metadata on tag edits.
- Bump VERSION to 0.261.230 and update release notes, framework, guide and API
  docs; add the upload-only intake fix document and tests.

Refs #1621

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
… edits

The full functional comparison against the base branch found three tests
that still asserted the removed behavior:

- test_content_screening_history: a release proof that doesn't match the
  content still leaves only the screening status; metadata edited after a
  release now stays available.
- test_group_document_fixture_parity / test_public_document_fixture_parity:
  a released screened document's metadata change returns the ordinary
  updated receipt (200) instead of queued (202).

Also records the base-branch comparison in the fix documentation.

Refs #1621

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Metadata edits now apply directly, so a metadata save never gets a queued
(202) receipt. This finishes that change in the client and the tests:

- documentOperations.ts accepts a metadata save only when the receipt is
  updated with HTTP 200; any other receipt, including a legacy queued 202
  one, is unconfirmed and keeps the draft.
- DocumentExplorer.tsx drops the queued branch that removed the document
  from the list and showed "Screening is queued"; a confirmed save shows
  "Metadata saved." and the document stays listed and available.
- The group and public metadata routes drop their unreachable 202 branch.
- The group and public UI fixtures no longer build a queued receipt.
- test_queued_metadata_acknowledgement_keeps_saved_content_held_for_screening
  becomes test_screened_metadata_edit_applies_directly_and_keeps_the_document_available,
  and the malformed-receipt test gains a legacy-queued-202 case that fails
  against the old explorer.
- Docs: V2 group document management, the fix doc and the release notes.

VERSION stays 0.261.230.

Refs #1621

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Saved and generated workflow results now take their access from the
workflow, run and group they belong to. Task and node results, structured
execution history, For each and Repeat history, run history previews,
chat Follow up on a workflow result and the document provenance run link
no longer re-resolve the documents a run read; those are kept as
provenance. Lineage, contract and hash integrity checks stay, as do the
container checks and the input-time checks when a workflow reads an
uploaded document. Each task attempt gets its own model fence.

Flow inspection marks an unavailable authored source on its own
selection row instead of denying the definition. Lineage failures answer
409, activity streams end with activity_unavailable, and
source_snapshot_changed is always false.

Version 0.261.231. Refs #1621 (layer 3a).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
test_native_source_revocation_blocks_saved_report_and_publication asserted
the old re-check of a saved Analyze result against its source. It now
revokes the native source after the Analyze result is saved and expects
the same end state as the happy-path test: the saved report reaches the
model and its artifact publishes once. The shared assertions moved into
assert_saved_report_published_once. The file's stale harness is
unchanged and noted in the fix doc.

Refs #1621.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) and others added 6 commits October 3, 2026 12:26
…ly-intake

Limit content screening intake to uploads and apply metadata edits directly (layer 2 of 4)
Brings in paullizer-workspace-knowledge-holds at 4b5346c, which now
includes the upload-only screening intake (0.261.230). Conflicts:
VERSION stays 0.261.231, and the 0.261.231 release notes sit above
0.261.230 and 0.261.229.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Brings in #1630 (Run as approval only when someone else authored the
revision), which the base branch released as 0.261.229.

Layer 1 also used 0.261.229, so its release notes move into the
v0.261.230 section alongside layer 2 (#1629, already merged into this
branch). Merging this pull request takes the base from 0.261.229 to
0.261.230 and delivers both layers. VERSION stays 0.261.230.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The base branch released #1630 (Run as) as 0.261.229, the number layer 1
had used. Layer 1 now ships with layer 2 in 0.261.230, so its fix doc,
user guide note and test headers say 0.261.230. FIX_VERSION only feeds
assert_app_version_at_least, which VERSION 0.261.230 satisfies.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…workflows

Stop re-checking saved workflow results against their source documents (screening layer 3a)
Syncs the local base-branch merge with #1631, which was merged into this
branch on GitHub. VERSION is 0.261.231 from layer 3a. The release notes
run 0.261.231 (layer 3a), 0.261.230 (layers 1 and 2) and 0.261.229
(Run as, from the base branch).

test_workflow_history_source_access.py keeps layer 3a's 0.261.231
header and labels layer 1's preview change 0.261.230. The layer 3a fix
doc now cites the layer 1 fix as 0.261.230.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit c53ef2d into paullizer-react-v2-ui Oct 3, 2026
11 checks passed
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 3, 2026
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>
@paullizer
Paul Lizer (paullizer) deleted the paullizer-workspace-knowledge-holds 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.

1 participant