Skip to content

Clearer saved-result error messages and repaired workflow test harnesses - #1635

Merged
Paul Lizer (paullizer) merged 4 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-lineage-error-wording-and-test-harnesses
Oct 5, 2026
Merged

Paul Lizer (paullizer) merged 4 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-lineage-error-wording-and-test-harnesses

Conversation

@paullizer

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

Copy link
Copy Markdown
Contributor

Summary

  • Clearer messages. AnalysisResultUnavailable used to have one message, "This analysis is unavailable because its source access could not be confirmed." That wording dates from when saved results re-checked their sources. It now picks its message by family:
    • Source: an input read can't read a document now, or the document changed.
    • Container: the conversation, workflow or run that holds the result is gone or isn't yours.
    • Saved result: the result, or something it depends on, is missing or changed.
  • The classification lives in explicit frozensets in functions_analysis_access.py. Codes were classified by what each raise site checks, not by name.
  • These places now show the family's message: the workflow runner's task error, the "result not saved" error, the loop item pause, saved-analysis explanation, Analyze save, the Analyze publication check, workflow progress, and the history placeholders.
  • No behavior change. The exception class, raise and catch sites, HTTP statuses and response code values are unchanged. The one exception is two former bare raises, which now carry container codes that map to the same response codes.
  • Repaired test harnesses. Six stale workflow test setups were fixed without loosening any assertion. 38 previously failing tests now reach their assertions and pass, including test_native_source_revocation_does_not_block_the_saved_report, the proof of Stop re-checking saved workflow results against their source documents (screening layer 3a) #1631's behavior.

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 (0.261.233 → 0.261.234; the base now ships 0.261.233), or not needed because this is docs-only
  • deployers/version.txt bumped, or not needed because deployers/ was not changed

Testing / validation

Message families (task 1)

  • python -m pytest functional_tests/test_analysis_unavailable_message_families.py → 39 passed. The file:
    • scans every AnalysisResultUnavailable(...) raise in application/single_app and fails on an unclassified code, a bare raise, an unknown family= value or an unresolved computed code. The exc.code raise in _authorize_frozen_document is resolved by walking the WorkflowLoopInputError codes that reauthorize_workflow_loop_document can raise.
    • checks each family's message and that codes are unchanged.
    • runs the real runner sequence for each family, for both the task error and the "not saved" error.
    • checks the chat explanation, save and publication routes, which all return 403 with the family message.
    • checks that the renamed codes keep every response code.
  • python -m pytest functional_tests/test_workflow_durable_routes.py → 13 passed. Workflow progress names a failed saved record, and a group membership refusal keeps its access message.

Harness repair (task 2)

  • Per-file before/after: each file runs in its own pytest process, with application/single_app on PYTHONPATH, over 468 related files. Before is an untouched worktree of e1e6949; after is this branch.

    • 287 failing nodes before, 249 after. 0 new failures, 38 fixed.
    • test_tabular_row_orchestration_scale.py hits the 25-minute timeout in both runs.
    File Before (e1e6949) After
    test_workflow_task_result_handoff.py 9 failed pass
    test_workflow_data_flow_execution.py 8 failed pass
    test_workflow_m365_rebase_integration.py 9 failed pass
    test_workflow_runtime_integration.py 4 failed pass
    test_analyze_workflow_publication_integration.py 8 errors pass
  • Round-trip harness, without PYTHONPATH: the 13 files built on it went from 1,857 failing tests to 0. The failure was No module named 'functions_workflow_chat_delivery'. All 13 also pass with PYTHONPATH set.

  • Isolation: test_analyze_artifact_phase7_rollout_rollback.py ran in one pytest process with the 6 files it used to break. Before: 5 collection errors and an interrupted run. After: 101 passed.

After merging the base (f1aeef1)

  • 23 files, each in its own pytest process with PYTHONPATH set, all pass: 868 passed, 0 failed. They are the new family test, the 5 repaired files above, every other test file this PR touches, the 7 other consumers of the inventory harness, and the 5 test files the base changed or added.
  • The 13 round-trip harness files, without PYTHONPATH: 1,871 passed, 0 failed.
  • Isolation, in one pytest process: 101 passed.
  • The checks below were rerun after the merge, against f1aeef1.

Checks

  • python scripts/check_xss_sinks.py --base-sha f1aeef13d --head-sha <head> <11 app files> → passed
  • python scripts/check_broken_access_control.py --base-sha f1aeef13d --head-sha <head> <11 py files> → passed
  • python scripts/check_swagger_routes.py <11 py files> → passed (2 route files)
  • 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
  • python scripts/build_docs_inventory.py → no content change. It produced a line-ending-only diff, which was restored.
  • python functional_tests/test_docs_app_surface_coverage.py → 7/7
  • python functional_tests/test_docs_site_quality.py → 6/6
  • git diff --check → clean
  • No V2 files changed, so V2 typecheck and build were not needed.

Documentation

  • Release notes updated: new v0.261.234 section with a Bug Fixes entry, above the base's v0.261.233 section, which is unchanged. The harness repair is internal and not listed.
  • Feature documentation updated: the public messages table in UPLOAD_ONLY_CONTENT_SCREENING.md.
  • Fix documentation updated: ANALYSIS_RESULT_UNAVAILABLE_MESSAGES_FIX.md and WORKFLOW_TEST_HARNESS_REPAIR_FIX.md.

Security checklist

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

Decisions and notes for review

Shared codes

  • Three raise sites share a code with another family, so they pass family=:
    • resolve_analysis_source_manifest raises analysis_source_manifest_invalid → source. The current lookup failed during an input read.
    • index_analysis_source_manifest raises the same code for an unauthorized assigned document → source.
    • load_workflow_artifact_binding raises generated_artifact_source_unavailable → saved result. The run records couldn't load; the scope checks keep container.
  • Bare raises:
    • authorize_analysis_sources and validate_sources now pass analysis_source_unavailable explicitly.
    • _load_authorized_message → analysis_message_unavailable, and _load_authorized_workflow → analysis_workflow_unavailable. Nothing branched on their old default.

Wording

  • The runner keys its text by the family's string value, falling back to source text. 70 functional test files compile the runner from source, so this avoids adding names to their namespaces. Unclassified codes fall back to the saved-result wording.
  • History placeholders for a saved analysis or saved workflow output no longer say "access could not be confirmed".

Left as is

  • These stay unchanged because their response codes are shared with genuine access refusals: the V2 text for workflow_result_access_denied, and generated file output_access_denied. The native bridge's "ownership or source access changed" also stays, because it describes an active computation's input check.

Harness repairs

  • The 4 test_workflow_runtime_integration.py failures came from WORKFLOW_SCHEDULED_TRIGGER_TYPES, which _run_authorized_workflow_impl now reads. That fixture already replaces _ensure_execution_context. The session / read_user_settings_snapshot fix was needed for the data-flow entrypoint test.
  • The functions_workflow_chat_delivery import failure from Stop re-checking workflow run sources in run history and after a task saves #1628 is the group round-trip harness. That harness loads real modules by file and didn't list the chat delivery contract. With PYTHONPATH set it didn't fail, but it left a stub-bound copy of the contract in sys.modules. Both are fixed.

Merge and renumbering

Push

  • git push origin returned 403: the current token has push: false on microsoft/simplechat. This branch was pushed to the paullizer/simplechat fork, as layers 2, 3a and 3b were.

Still failing, out of scope and unchanged

  • test_content_screening_pipeline.py and test_content_screening_reviews.py.
  • Tests that need Azure config, V2 node_modules or the dev server.

Paul Lizer (paullizer) and others added 3 commits October 3, 2026 17:31
AnalysisResultUnavailable now picks its wording by message family: a source
document that can't be read now (input reads only), the conversation, workflow
or run that holds a result, or the saved result itself. The families are held
in explicit frozensets in functions_analysis_access.py, with family= only at
the three raise sites that share a code with another family. Bare raises now
pass a code; the message and workflow binding mismatches use container codes
that map to the same response codes. The workflow runner, loop item pause,
saved analysis explanation, Analyze save and publication check, and workflow
progress route show the family's message. Codes and HTTP statuses are unchanged.

A new functional test scans every raise in application/single_app and fails
for an unclassified code, a bare raise or an unresolved computed code.

The stale workflow test harnesses are repaired without changing assertions:
real generated_file_publication_allowed and schedule rules in the inventory
harness, a signed-in owner context for the run entrypoint test, the model
budget patch retargeted to resolve_model_token_budget, the chat delivery
contract loaded by the round-trip harness, and the Phase 7 planner stubs
scoped to their module.

Version 0.261.233. Refs microsoft#1621.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The base now ships its own v0.261.233 release-notes section (microsoft#1626, microsoft#1633),
so this branch's entry moves to a new v0.261.234 section above it. The base
section is kept verbatim. config.py merged cleanly because both sides set
0.261.233; the renumbering follows in the next commit.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The base now ships 0.261.233, so VERSION moves to 0.261.234 and every
version label this PR added follows: both fix docs, the Upload-Only Content
Screening notes, and the functional test headers, including the new test's
assert_app_version_at_least floor. The base's own 0.261.233 references are
unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread functional_tests/test_analyze_artifact_phase7_rollout_rollback.py Fixed
CodeQL (py/call/wrong-arguments) flagged test(*arguments) in the __main__
runner of test_analyze_artifact_phase7_rollout_rollback.py, because it can't
pair each test with its own argument tuple through the loop. The runner now
iterates over (name, call) pairs whose calls take no arguments, so every
call site shows its own arity. Test-only; no version bump.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit efee707 into microsoft:paullizer-react-v2-ui Oct 5, 2026
11 checks passed
@paullizer
Paul Lizer (paullizer) deleted the paullizer-lineage-error-wording-and-test-harnesses branch October 5, 2026 16:30
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 5, 2026
paullizer-react-v2-ui merged #1635 and published v0.261.234, which this
branch used for Phase 1.

The integration branch's sections are kept exactly as published. This
branch's nine sections shift up one, to v0.261.235 through v0.261.243,
and config.py becomes 0.261.243. Every file only this branch changed is
checked to equal its previous content with those versions shifted, every
file only the integration branch changed is unchanged, and the release
notes are the integration branch's file plus this branch's nine
sections.

test_workflow_task_result_handoff.py conflicted on its header only. It
keeps #1635's "Harness dependencies restored in: 0.261.234" line with
this branch's Version, now 0.261.238, and both harness changes: #1635's
publication policy and schedule rules, and this branch's merge document
action constant. It now passes. functions_workflow_runner.py merged
cleanly: #1635 rewords saved-result failures in
_execute_workflow_task_sequence, apart from this branch's merge task.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 5, 2026
microsoft#1635 took 0.261.234, so this PR's release notes section moves to v0.261.235,
above microsoft#1635's section.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 5, 2026
microsoft#1635 merged into paullizer-react-v2-ui as 0.261.234 first. Moves VERSION, the
feature and guide docs, and this PR's test headers and version floors to
0.261.235.

Refs microsoft#1634

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 5, 2026
V2 moved to efee707 (VERSION 0.261.234) when #1635 merged: saved-result
error messages by family and repaired workflow test harnesses.

Conflicts:
- config.py: keep this branch's 0.261.238, still above V2's 0.261.234 and
  the claimed 0.261.235 to 0.261.237.
- release_notes.md: keep both sections, 0.261.238 above 0.261.234.

test_workflow_draft_save_parity.py auto-merged: #1635 adds the chat delivery
contract to REAL_MODULES, and this branch's _restored_modules still undoes
every sys.modules change made while the harness loads.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 5, 2026
#1635 loads the chat delivery contract as a real module, so it no longer
reaches the harness only as a transitive import. The comment now describes
what _restored_modules undoes without naming that module.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 6, 2026
V2 is still at 0.261.233. microsoft#1635, microsoft#1636, microsoft#1637 and microsoft#1638 claim .234 to .236,
so this branch takes .237. Every 0.261.234 reference moves to 0.261.237:
config.py, the release notes header, the feature docs, the chat-controls
reference and the test headers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 6, 2026
Brings in microsoft#1635 (clearer saved-result error messages and repaired workflow
test harnesses, released as 0.261.234). The only conflicts were VERSION in
config.py, kept at 0.261.237 because that is still above V2's 0.261.234,
and the top of release_notes.md, where both sides added a section; both are
kept intact under their own headings, v0.261.237 above v0.261.234.

Refs microsoft#1546

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit to paullizer/simplechat that referenced this pull request Oct 6, 2026
microsoft#1635 split _workflow_runtime_response's PermissionError branch: a saved record that fails its own check (AnalysisResultUnavailable) now answers its own 403 text before the access 403. The action-client suite pinned the old single-return shape, so it failed after the V2 merge. The pin now reads the outer branch and requires every return in it to be a 403, which V2 shows as its fixed no-access sentence whatever the server says.

Refs microsoft#1546

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