Skip to content

Improve CI-fix Azure queue failure diagnostics - #39243

Merged
kubaflo merged 2 commits into
mainfrom
pureween-fix-ci-fixer-azure-queue
Oct 9, 2026
Merged

kubaflo merged 2 commits into
mainfrom
pureween-fix-ci-fixer-azure-queue

Conversation

@PureWeen

@PureWeen PureWeen commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description of Change

Preserve bounded, redacted Azure DevOps response details when the trusted CI-fix dispatcher receives a nontransient queue failure such as HTTP 400.

The first genuine bot PR canary proved native maui-pr integration but the dispatcher lost Azure's response body for all queue POST failures, leaving only 400 (Bad Request). This change extracts Azure's message and typeKey when available, bounds fallback response text, redacts common credential forms, and keeps the existing fail-closed behavior: one POST, no retry or reconciliation for nontransient failures.

Diagnostics-only readiness: this change is ready for human deployment, but it does not claim to restore Azure queue acceptance. The provider-side HTTP 400 root cause remains unproven and queueing is not restored. After human merge, the next legitimate automatic trusted dispatcher execution must supply the actual redacted Azure response before any payload, provider, or configuration change is justified. No manual dispatcher rerun or direct Azure queue POST is part of this validation.

Validation at exact head ba0fd0e822e2dce0fce48ee3eb4e9a1f74e2d5f1:

  • Authored run using the confirmed Pester 5.9.0 manifest: 82 passed, 0 failed.
  • Independent parent run using the existing Pester 6.2.0 artifact: 82 passed, 0 failed, 0 skipped.
  • Independent focused patch review: no blocker found; exact two-file scope, clean head, open non-draft PR targeting main verified before and after the run.
  • git diff --check: passed.

Issues Fixed

Refs #39223

Preserve bounded, redacted Azure response details for nontransient queue failures so provider-side HTTP 400 validation errors are actionable without changing queue retry or acceptance semantics.

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

Copilot-Session: 2c742a56-d991-47ed-801b-52bec21dc948
Copilot AI balanced review requested due to automatic review settings October 8, 2026 01:48
@PureWeen
PureWeen deployed to copilot-pat-pool October 8, 2026 01:48 — with GitHub Actions Active
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 39243

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 39243"

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@PureWeen
PureWeen deployed to copilot-pat-pool October 8, 2026 01:48 — with GitHub Actions Active
@PureWeen
PureWeen deployed to copilot-pat-pool October 8, 2026 01:49 — with GitHub Actions Active
@PureWeen
PureWeen deployed to copilot-pat-pool October 8, 2026 01:51 — with GitHub Actions Active
@PureWeen
PureWeen deployed to copilot-pat-pool October 8, 2026 01:52 — with GitHub Actions Active
@PureWeen
PureWeen deployed to copilot-pat-pool October 8, 2026 01:53 — with GitHub Actions Active

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Valid JSON fallback responses can expose token fields written as JSON key-value pairs.

1 open finding
What changed in this PR

Improves Azure DevOps queue-failure diagnostics while preserving existing fail-closed behavior.

Changes:

  • Extracts, bounds, and redacts Azure error details.
  • Adds tests for structured and plain-text failures.
  • One JSON credential-redaction gap remains.
File Description
.github/​scripts/​Queue-CiFixAzdoValidation.ps1 Formats queue failure diagnostics.
.github/​scripts/​Queue-CiFixAzdoValidation.Tests.ps1 Tests diagnostics and retry safety.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment thread .github/scripts/Queue-CiFixAzdoValidation.ps1
@kubaflo

This comment has been minimized.

@kubaflo

kubaflo commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

/azp run

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Oct 8, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
3 pipeline(s) were filtered out due to trigger conditions.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Note

🔍 /review started

AzDO build 15608582 is running for android.

The s/agent-review-in-progress label stays on this PR while the run is active. The final recommendation and outcome labels are posted only after Gate, expert review, and Deep UI tests finish.

MauiBot

This comment was marked as outdated.

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) and removed s/agent-review-in-progress AI review is currently running for this PR labels Oct 8, 2026

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot found something

Cover valid JSON fallback responses whose quoted credential fields previously bypassed assignment-style redaction, while preserving safe diagnostic fields and existing queue failure semantics.

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

Copilot-Session: 2c742a56-d991-47ed-801b-52bec21dc948

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The trusted dispatcher changes appear sound, but the current Pester check is failing and other checks remain pending.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@kubaflo

This comment has been minimized.

@kubaflo

kubaflo commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
3 pipeline(s) were filtered out due to trigger conditions.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Note

🔍 /review started

AzDO build 15636278 is running for android.

The s/agent-review-in-progress label stays on this PR while the run is active. The final recommendation and outcome labels are posted only after Gate, expert review, and Deep UI tests finish.

@kubaflo
kubaflo merged commit 54ab39e into main Oct 9, 2026
12 of 17 checks passed
@kubaflo
kubaflo deleted the pureween-fix-ci-fixer-azure-queue branch October 9, 2026 21:32
@github-actions github-actions Bot added this to the .NET 10 SR12 milestone Oct 9, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review Summary

@PureWeen — new AI review results are available based on commit 4921c90.

Gate No Tests Confidence Low Platform Android


🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix

Gate Result: ⚠️ SKIPPED

No tests were detected in this PR.

Recommendation: Add tests to verify the fix using the write-tests-agent.


📋 Pre-Flight — Context & Validation

Pre-Flight Context

Reported problem

PR #39243 is a diagnostics-only change for the trusted CI-fix dispatcher. A bot-created PR canary reportedly reached the native maui-pr queue operation, but a nontransient Azure DevOps HTTP 400 surfaced only the generic 400 (Bad Request) exception; the Azure response body containing the actionable provider validation error was discarded. The provider-side cause and restoration of queue acceptance remain unknown.

The PR references #39223, an open net11.0 CI issue where Windows and macOS Debug solution builds fail because VersionLessThan receives an empty version. That issue motivated the validation attempt but is not fixed by this PR.

GitHub metadata currently records the PR as merged into main on 2026-10-09, with final submitted head 4921c90376b788d272eec02a1ea07fcbe3f69be7.

Changed files and mechanism

The immutable diff changes exactly two PowerShell files:

  • .github/scripts/Queue-CiFixAzdoValidation.ps1

    • Adds Get-AzdoQueueFailureMessage.
    • Reads the response text from ErrorRecord.ErrorDetails.Message.
    • For JSON responses, preferentially emits Azure’s top-level message and optional typeKey; otherwise it retains bounded fallback text.
    • Normalizes tabs/newlines and redacts Basic/****** selected JSON credential fields, assignment-style token values, and JWT-shaped strings.
    • Limits diagnostic detail to 1,024 characters by default, with an accepted range of 256–4,096 and an explicit truncation suffix.
    • Preserves the original exception message when no usable response detail exists.
    • Changes only the nontransient queue-POST catch path from rethrowing the original error to throwing the constructed diagnostic message. Transient classification, retries, sleeps, and duplicate-build reconciliation remain outside this new branch.
  • .github/scripts/Queue-CiFixAzdoValidation.Tests.ps1

    • Includes the new helper in the test module’s selected function set.
    • Adds Pester coverage for:
      • Extracting Azure message/typeKey from an HTTP 400 while retaining one POST and no duplicate lookup.
      • Redacting and truncating a non-JSON response.
      • Redacting quoted JSON credential fields while preserving a safe field.
    • A prior review thread identified that valid JSON fallback bodies could expose quoted token fields. The final commit adds the corresponding redaction and test; that thread is marked resolved.

Security and platform-sensitive paths

The affected script is trusted CI infrastructure rather than MAUI application/runtime code. Its unchanged workflow, .github/workflows/ci-fix-azdo-validation.yml, runs PowerShell on ubuntu-latest for pull_request_target and trusted fixer workflow_run events. It sparsely checks out the trusted workflow revision, does not fetch or execute the PR head, uses persist-credentials: false, and receives Azure OIDC client settings plus a read-only GitHub token.

Relevant platform boundaries are therefore:

  • GitHub Actions/Linux/PowerShell: response/error-record behavior and Pester compatibility are directly relevant.
  • Azure DevOps REST provider: the diagnostic depends on how failed Invoke-RestMethod calls populate ErrorDetails.Message.
  • Android: Android is the requested platform for later testing, but this diff contains no Android source or device behavior. Android validation can exercise the selected review lane only indirectly.
  • Windows/macOS: these are the platforms affected by linked issue #39223. Android-only testing cannot establish whether that originating build failure is fixed, and this PR does not claim to fix it.

Validation requirements and available evidence

  • Gate: ⚠️ skipped because Gate detected no tests. It must not be rerun. The submitted diff nevertheless contains Pester tests; why Gate did not classify them is unknown.
  • The PR description reports 82 passing Pester tests under versions 5.9.0 and 6.2.0, but those claims are tied to commit ba0fd0e822e2dce0fce48ee3eb4e9a1f74e2d5f1, not the final head that added JSON credential redaction.
  • At the final head, GitHub check metadata shows Pester scripts concluded failure. The failure logs/reason were unavailable through the read-only context gathered here.
  • The three maui-pr, maui-pr-devicetests, and maui-pr-uitests checks were neutral after being filtered by trigger conditions; they do not establish functional validation.
  • Validation should specifically establish final-head behavior for:
    • JSON and non-JSON Azure error shapes.
    • Missing or whitespace-only response details.
    • Malformed JSON and PowerShell-version-specific conversion exceptions.
    • All intended credential forms, line normalization, and exact truncation bounds.
    • One POST with no retry or duplicate reconciliation for nontransient failures.
    • Unchanged transient retry/reconciliation behavior.
    • Acceptability of replacing the original thrown error record with a newly constructed diagnostic exception/message.
    • End-to-end emission of a useful redacted Azure response during the next legitimate automatic dispatcher execution, without manually replaying the dispatcher or issuing a direct Azure queue POST.

Remaining uncertainties

  • The actual Azure response that caused the original HTTP 400 is unavailable, so its shape and provider validation message are unknown.
  • The Azure queue-rejection root cause remains unproven, and successful queue acceptance has not been demonstrated.
  • The reason the final-head Pester scripts check failed is unknown.
  • The PR description’s successful test counts were not independently verified and do not cover the recorded final head.
  • Whether every Invoke-RestMethod failure shape exposes the body through ErrorDetails.Message is unconfirmed.
  • Only the response-detail portion is explicitly sanitized by the new helper; whether an exception message itself could contain sensitive material is unestablished.
  • No post-merge automatic dispatcher diagnostic was available.
  • This is context gathering, not an exhaustive code or security review, and it does not replace the dedicated expert review.

🔬 Code Review — Deep Analysis

Code Review — PR #39243

Independent Assessment

What this changes:
The PR adds Get-AzdoQueueFailureMessage and wires it into the nontransient queue-POST failure path in .github/scripts/Queue-CiFixAzdoValidation.ps1 so thrown errors include bounded/redacted Azure response detail (preferring JSON message + optional typeKey, else fallback body text). It also adds Pester tests for nontransient behavior preservation, truncation/redaction, and JSON credential-field redaction in fallback responses.

Inferred motivation:
Make Azure DevOps queue failures diagnosable (especially HTTP 400 validation responses) without changing the one-POST/no-retry semantics for nontransient failures.

Reconciliation with PR Narrative

Author claims: diagnostics-only change; preserve fail-closed queue semantics; redact sensitive response details; prior successful local Pester runs.
Agreement/disagreement:

  • Agree on mechanism and semantics preservation in source/tests at final head.
  • Final-head check evidence does not validate the narrative’s earlier passing-test claim for commit ba0fd0e...; current head is 4921c903... and has a failed Pester scripts check.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
JSON fallback could leak {"access_token":"..."} style secrets Copilot inline comment on .github/scripts/Queue-CiFixAzdoValidation.ps1 ✅ Fixed Final head adds JSON key/value redaction regex at .github/scripts/Queue-CiFixAzdoValidation.ps1:127 and regression test at .github/scripts/Queue-CiFixAzdoValidation.Tests.ps1:1185-1204.

No unresolved prior ❌ Error findings were found in current code.

Blast Radius Assessment

  • Runs for all instances: No (only error path of CI-fix Azure queue POST failures, not app/runtime flow).
  • Startup impact: No MAUI app startup impact (GitHub Actions/PowerShell infra script only).
  • Static/shared state: No new mutable shared state introduced.
  • Platform relevance: Requested platform was Android, but this diff is CI PowerShell/GitHub Actions + Azure DevOps boundary logic; no Android runtime/control/handler code is touched.

CI Status

  • gh pr checks --required could not be executed due unauthenticated gh in this environment (tool-unavailable fallback applies).
  • Independent head check-run evidence (4921c903...) shows:
    • Pester scripts: completed / failure
    • Build Insights: in_progress
    • maui-pr, maui-pr-uitests, maui-pr-devicetests: neutral
  • Classification: undetermined for merge-readiness (required-check view unavailable here; at least one relevant check is failed and another pending).
  • Action taken: confidence capped low; no LGTM.

Findings

No new concrete actionable code defect was validated from current diff/source/tests.

Failure-Mode Probing

  • Nontransient POST path: still one POST, no reconciliation/retry (guarded by if (-not Test-IsTransientHttpException) { throw (Get-AzdoQueueFailureMessage ...) } at .github/scripts/Queue-CiFixAzdoValidation.ps1:827-829), with explicit test coverage at .github/scripts/Queue-CiFixAzdoValidation.Tests.ps1:1131-1162.
  • Fallback secret redaction when JSON has no top-level message: now includes JSON key/value credential redaction plus assignment and bearer/basic forms (.ps1:126-129), covered by test .Tests.ps1:1185-1204.
  • Truncation/normalization bounds: newline/tab normalization and bounded truncation with suffix remain deterministic (.ps1:125,131-134) with explicit test (.Tests.ps1:1164-1183).
  • Transient reconciliation semantics: unchanged branch preserves ambiguous-POST reconciliation behavior; existing tests around “may have been accepted” flows remain present in same file.

External Output Contract

Consumer token/pattern Producer location Producer emission condition Consumer assumption Ordinary negative case Downstream effect
ErrorRecord.ErrorDetails.Message body; JSON keys message/typeKey PowerShell Invoke-RestMethod failure record content from Azure DevOps queue API response body Present when provider returns body text in failure record details Body may contain actionable provider diagnostics and may contain sensitive tokens needing redaction/bounds Nontransient queue failure with non-JSON or JSON lacking top-level message Consumer keeps fallback text, applies normalization/redaction/truncation, throws composed diagnostic; no retry/reconciliation for nontransient failures
Redaction patterns for bearer/basic, assignment tokens, JSON credential fields, JWT-like strings Same response-body source as above Tokens appear in provider/body text Redaction should sanitize before throw Valid JSON fallback with credential fields but no top-level message Final head now redacts these values before composing thrown message

Applicable Security / External-Output Contract Analysis

  • This change is in trusted infra scripts and does not execute untrusted PR code paths directly.
  • It handles external provider output (Azure response body) and now applies bounded sanitization before surfacing diagnostics.
  • The previously identified JSON fallback credential leak mechanism is source-fixed and test-backed at final head.

Verdict: NEEDS_DISCUSSION

Confidence: low

Summary:
The submitted code change appears mechanically sound for its intended diagnostics behavior and preserves nontransient retry/reconciliation semantics, with the prior JSON-redaction defect now fixed and regression-tested. However, final-head CI evidence is not in a merge-ready state from this environment (Pester scripts failed; another check pending; required-check query unavailable via unauthenticated gh). Given undetermined/failing check state, this review cannot recommend LGTM.


Refinement-threshold decision (required)

Decision: NOT MET for additional code-refinement request.

Reason: after validating source and tests at final head, no concrete new actionable code defect or unresolved behavioral mechanism was established beyond CI/check-state uncertainty. Current blocker is evidence/verification state (failed/pending checks), not a newly proven implementation bug in changed lines.


🛠️ Try-Fix — Analysis & Comparison

Alternative generation: not requested

Evidence-first mode intentionally omits routine Try-Fix attempts. This is not a failed
attempt, a completed alternative search, or evidence that alternatives have no value.
The expert review may still produce one evidence-backed PR refinement.


📝 PR Finalize — Recommended Title & Description

Assessment: ✏️ Recommend updating — the implementation summary remains accurate, but the validation section applies to an earlier head and does not disclose the failed final-head Pester check.

Recommended title

[CI] CI-fix: Preserve redacted Azure queue failure diagnostics

Recommended description

### Description of Change

Preserve bounded, redacted Azure DevOps response details when the trusted CI-fix dispatcher receives a nontransient queue failure such as HTTP 400.

The first genuine bot PR canary proved native `maui-pr` integration, but the dispatcher lost Azure's response body for queue POST failures and surfaced only `400 (Bad Request)`. The provider-side queue-rejection cause remains unknown.

- `.github/scripts/Queue-CiFixAzdoValidation.ps1` adds `Get-AzdoQueueFailureMessage`, which reads `ErrorRecord.ErrorDetails.Message`, prefers Azure's top-level `message` and optional `typeKey` for JSON responses, and otherwise retains bounded fallback text. It normalizes tabs and newlines, redacts common Basic/Bearer, assignment-style, JSON credential-field, and JWT-shaped secrets, and limits diagnostic detail to 1,024 characters by default with an accepted 256–4,096 range and an explicit truncation suffix.
- The nontransient queue-POST catch path now throws the constructed diagnostic message. It still performs one POST with no retry or duplicate-build reconciliation; transient classification, retries, sleeps, and ambiguous-POST reconciliation remain unchanged.
- `.github/scripts/Queue-CiFixAzdoValidation.Tests.ps1` adds Pester coverage for Azure `message`/`typeKey` extraction, non-JSON redaction and truncation, JSON credential-field redaction, and preservation of the nontransient one-POST behavior.

**Diagnostics-only scope:** this change does not claim to restore Azure queue acceptance. After human merge, the next legitimate automatic trusted dispatcher execution must supply the actual redacted Azure response before any payload, provider, or configuration change is justified. No manual dispatcher rerun or direct Azure queue POST is part of this validation.

### Validation

- At final submitted head `4921c90376b788d272eec02a1ea07fcbe3f69be7`, the trusted Gate was skipped because it detected no tests, despite the Pester test changes.
- The final-head `Pester scripts` check failed; the failure reason was unavailable to this review. `Build Insights` was still pending, while `maui-pr`, `maui-pr-devicetests`, and `maui-pr-uitests` were neutral after trigger filtering.
- At earlier head `ba0fd0e822e2dce0fce48ee3eb4e9a1f74e2d5f1`, the author reported 82 passing tests with Pester 5.9.0 and an independent run reported 82 passing tests with Pester 6.2.0. Those runs predate the final JSON credential-field redaction change and do not validate the final submitted head.
- The earlier-head focused review verified the two-file scope and reported `git diff --check` passing.

### Platforms

This change affects trusted GitHub Actions/Linux/PowerShell CI infrastructure and the Azure DevOps REST boundary. It does not change Android or other MAUI runtime behavior.

### Issues Fixed

Refs #39223

🏁 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Trusted evidence-first context consumed
Code Review NEEDS_DISCUSSION (low) 0 errors, 0 warnings; final-head validation remains unresolved
Gate ⚠️ SKIPPED No tests detected; Gate did not establish that the submitted fix passes
Try-Fix not requested Intentionally omitted by evidence-first mode
Refinement NOT GENERATED Expert review found no source-backed actionable defect meeting the refinement threshold
Report ✅ COMPLETE Only real candidates were compared

Code Review and Candidate Comparison

Candidate Implementation evidence Validation evidence Assessment
pr The submitted helper preserves nontransient one-POST/no-reconciliation behavior, bounds and normalizes provider detail, and redacts the previously identified JSON credential-field form. The expert review found no concrete implementation defect at final head. Gate was skipped. The relevant final-head Pester scripts check failed, Build Insights was still pending, and the required-check query was unavailable; the 82-test passing claims in the PR description apply to an earlier head. Sole real candidate and therefore selected, but not demonstrated merge-ready.

Try-Fix: not requested. No try-fix-N candidates were generated, and no pr-plus-reviewer refinement was implemented because the expert evidence threshold was not met.

Selected Fix: PR — it is the only implemented candidate and the expert review found no source-backed reason to alter it. This selection does not override the skipped Gate or unresolved final-head check evidence.

Summary

Request changes because the submitted PR lacks successful final-head validation: Gate was skipped, the relevant Pester check failed, and another check remained pending. The expert review classified the code as NEEDS_DISCUSSION with low confidence rather than identifying a defect suitable for a reviewer patch.

Root Cause

The trusted CI-fix dispatcher discarded the actionable Azure DevOps response body when a nontransient queue POST failed, leaving only the generic HTTP exception text. The provider-side reason for queue rejection remains unknown and is outside this diagnostics-only change.

Fix Quality

The submitted fix is focused and preserves the existing fail-closed queue semantics while adding bounded, normalized, redacted provider diagnostics and targeted Pester coverage. Its implementation appears sound from source inspection, including the final JSON credential-field redaction, but failed or missing final-head validation prevents an approval recommendation.


🧭 Next Steps — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

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

Labels

s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants