Skip to content

Improve Memory Leak workflows: 6h fixer cadence + merged-PR de-dup/auto-close + re-file guard - #36524

Open
kubaflo wants to merge 20 commits into
mainfrom
leak-fixer-3h-schedule
Open

Improve Memory Leak workflows: 6h fixer cadence + merged-PR de-dup/auto-close + re-file guard#36524
kubaflo wants to merge 20 commits into
mainfrom
leak-fixer-3h-schedule

Conversation

@kubaflo

@kubaflo kubaflo commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

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!

This PR tunes the two agentic memory-leak workflows — daily-leak-hunter (files [leak-scan] issues) and leak-fixer (turns them into [leak-fix] PRs) — for cadence and to stop wasting runs re-processing leaks that are already fixed on main.

1. Fixer cadence: every 12h → every 6h

The fixer now runs 4×/day instead of 2×, so review feedback on open [leak-fix] PRs (Track C) and new fixes (Track A) are picked up faster. Only the fixer cadence changes; the hunter keeps its existing every-12h cadence.

2. Fixer: stop rebuilding already-fixed leaks

The fixer's de-dup only checked open and closed-unmerged fix PRs — never merged ones. Merged fixes frequently carry Fixes #<upstream> instead of the [leak-scan] number, so GitHub never auto-closed the scan issue. The fixer then re-picked it oldest-first, rebuilt MAUI from source (~10-20 min), hit "already fixed on main", and skipped without closing — repeating every run.

  • Step 3 gate (d): if a merged [leak-fix] PR already covers the same rooting Type.Member (or refs the issue), close the [leak-scan] issue (AI-attributed comment linking the merged PR) instead of rebuilding. This is the only path that auto-closes a scan issue — it is backed by workflow-owned provenance (a merged [leak-fix] PR).
  • Step 6: when the regression test is green on unpatched main, record skipped: test green on unpatched main (issue left open) — it does not close the scan issue. A single green result from a freshly-authored repro isn't proof the leak is gone (post-review change, see below).
  • Step 10: require Fixes #<N> to be the [leak-scan] number (any separate upstream issue goes as an optional Refs: line, never a second Fixes:) so the scan issue auto-closes on merge going forward.
  • New close-issue safe-output with deterministic guards required-title-prefix: "[leak-scan] " + required-labels: [agentic-workflows], so only this workflow's own scan issues can ever be closed. Write access lives in the isolated safe-outputs/conclusion jobs; the agent stays read-only.
  • Dry-run safety: the close-issue path (gate (d)) is gated behind dry_run, matching Track C / Step 10 — a dry run prints DRY RUN — would close #<N> instead of closing, so dry_run=true is a true no-side-effect mode.

3. Hunter: don't re-file leaks already fixed on main

The hunter verifies against the shipped Microsoft.Maui.Controls 10.0.0 package, where a leak fixed on main still reproduces until the fix ships — so the empirical test alone can't tell, and the old "closed issues may be re-filed" rule would recreate deliberately-closed issues.

  • Step 2: build a fixed-on-main Type.Member set from merged [leak-fix] PRs ONLY (durable, workflow-owned provenance that a fix landed) and skip re-filing those. Off-contract titles with no dotted Type.Member keep a normalized-title fallback key instead of being dropped.
  • Tighten Hard Rule 5 / Step 6: a leak fixed on main by a merged [leak-fix] PR is never re-filed; a leak whose only prior scan issue was closed with no merged fix PR (any close reason) may be re-filed if it still reproduces — a close reason is not proof.

Review feedback addressed (rev 218f465)

Following the Copilot + adversarial review, issue closure and re-file suppression are now strictly provenance-gated — the two data-loss / regression paths the reviewers flagged are removed:

  • Data loss (COMPLETED ≠ fixed): dropped the "[leak-scan] closed as completed" source from the hunter's fixed-on-main set — a maintainer closing a still-reproducing issue no longer permanently suppresses it. Only a merged [leak-fix] PR counts as fixed-on-main.
  • Regression (green test ≠ fixed): the fixer's Step 6 no longer auto-closes on a green-on-main test; closure is reserved for the merged-PR gate (d).
  • Security (unscoped close-issue): added required-title-prefix + required-labels guards so a hallucinated / injected number can't close an unrelated issue.
  • gh pr list paging: all four de-dup gates now pass --limit 200.
  • Reworded the issues: write comment (accurate about the conclusion + safe-outputs jobs) and clarified the Refs: / Fixes: PR-body placeholder (distinct <UPSTREAM> token).

Compilation

Both .md sources are recompiled with gh aw compile (v0.80.9, the version pinned in .github/aw/actions-lock.json) — 0 errors, 0 warnings, and a clean recompile of the committed sources is a verified no-op (no toolchain drift). The .lock.yml files are regenerated, not hand-edited. In this revision the fixer lock's only semantic change is the close_issue guard (required_title_prefix + required_labels); the hunter lock changes only its body_hash (prompt-only, no new permissions).


Note

🔍 AI-generated PR — authored via GitHub Copilot CLI on behalf of @kubaflo. Please review the workflow prompt changes carefully before merging.

Increase the scheduled cadence of the Memory Leak Fixer agentic
workflow from every 12h to every 3h so open [leak-scan] issues get
a [leak-fix] PR (and review-feedback responses) turned around faster.

Only the fixer changes; the Daily Memory Leak Hunter stays at 12h.

Edited the `schedule:` directive in leak-fixer.md and recompiled the
lock file with gh aw (v0.80.9): cron "20 */12 * * *" -> "20 */3 * * *".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1257a460-520a-4b7a-91d5-61f39054ea59
Copilot AI review requested due to automatic review settings July 11, 2026 20:43
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 11, 2026 20:43 — with GitHub Actions Inactive
@github-actions

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 -- 36524

Or

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

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.

Pull request overview

Updates the Memory Leak Fixer agentic workflow schedule to run more frequently, improving turnaround time for generating [leak-fix] PRs from open [leak-scan] issues.

Changes:

  • Increased workflow cadence from every 12h → every 3h in the source .md workflow definition.
  • Recompiled the generated lock workflow to update the underlying cron schedule and friendly comment accordingly.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
.github/workflows/leak-fixer.md Updates gh-aw schedule to every 3h and aligns the related noop/idle-run comment text.
.github/workflows/leak-fixer.lock.yml Updates generated cron from 20 */12 * * * to 20 */3 * * * (plus the friendly-format comment).

@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 11, 2026 20:46 — with GitHub Actions Inactive
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 11, 2026 20:47 — with GitHub Actions Inactive
@github-actions github-actions Bot added the area-infrastructure CI, Maestro / Coherency, upstream dependencies/versions label Jul 11, 2026
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 11, 2026 20:47 — with GitHub Actions Inactive
Adjust the fixer schedule from every 3h to every 6h per feedback,
so it runs 4 times a day. Recompiled the lock file with gh aw:
cron "20 */3 * * *" -> "20 */6 * * *".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1257a460-520a-4b7a-91d5-61f39054ea59
Copilot AI review requested due to automatic review settings July 11, 2026 20:49
@kubaflo kubaflo changed the title Run Memory Leak Fixer every 3h instead of every 12h Run Memory Leak Fixer every 6h instead of every 12h Jul 11, 2026
@kubaflo kubaflo added the area-ai-agents Copilot CLI agents, agent skills, AI-assisted development label Jul 11, 2026

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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 11, 2026
@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jul 11, 2026
MauiBot

This comment was marked as outdated.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 11, 2026
Beyond the 6h fixer cadence, teach the two agentic memory-leak workflows to
stop re-processing leaks that are already fixed on main.

Leak Fixer (leak-fixer.md):
- New close-issue safe-output (issues:write scoped to the safe-outputs job).
- Step 3 gate (d): if a MERGED [leak-fix] PR already covers the same rooting
  Type.Member (or refs the issue), close the [leak-scan] issue instead of
  rebuilding MAUI from source. Merged fixes often reference an upstream issue
  number, so GitHub never auto-closed the scan issue and it was re-picked and
  rebuilt every run.
- Step 6: when the regression test is already green on unpatched main, close the
  scan issue (already fixed) instead of silently skipping.
- Step 10: require Fixes #<N> to be the [leak-scan] number (upstream refs go as
  Refs:, never a second Fixes:) so the scan issue always auto-closes on merge.

Daily Leak Hunter (daily-leak-hunter.md):
- Step 2: build a fixed-on-main Type.Member set from merged [leak-fix] PRs and
  [leak-scan] issues closed as completed; skip re-filing those. Prevents a
  re-file loop, since the hunter tests the shipped 10.0.0 package where a
  fixed-on-main leak still reproduces.
- Tighten Hard Rule 5 / Step 6 wording: only re-file leaks closed as NOT PLANNED,
  never those fixed on main.

Recompiled both .lock.yml via gh aw compile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1257a460-520a-4b7a-91d5-61f39054ea59
Copilot AI review requested due to automatic review settings July 12, 2026 16:16
@kubaflo kubaflo changed the title Run Memory Leak Fixer every 6h instead of every 12h Improve Memory Leak workflows: 6h fixer cadence + merged-PR de-dup/auto-close + re-file guard Jul 12, 2026

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/daily-leak-hunter.md Outdated
…timeline)

The maintainer re-open guard fetched the issue timeline with a
`|| echo '[]'` fallback. On ANY timeline fetch/parse failure it wrote an
empty timeline, so REOPENED_AT became empty, the re-open override did NOT
fire, and the destructive close-issue/rebuild path ran -- re-closing a
maintainer-reopened [leak-scan] issue every 6h and posting a false
"already fixed" comment.

Fix (fail CLOSED on this destructive path): only compute the re-open time
when the timeline is BOTH fetched successfully AND parses as a JSON array.
Otherwise write the override sentinel so close-issue/rebuild is skipped and
the issue is left open. The agent emits a distinct skip reason
("re-open guard unverified (timeline lookup failed)") for the fail-closed
case vs. a genuine maintainer override.

Empirically verified all four timeline scenarios: (1) API failure and
(2) non-array garbage now fail closed (skip close); (3) genuine re-open and
(4) normal-no-reopen behave exactly as before.

Recompiled leak-fixer.lock.yml with gh aw v0.80.9 (body_hash only;
frontmatter and actions-lock.json unchanged).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 767d2d21-494b-41fb-8e8b-4410f9cc1b4b
Copilot AI review requested due to automatic review settings July 15, 2026 21:15
@kubaflo

kubaflo commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

🔍 AI review round — fail-open re-open guard fixed (ecda5f43d5b)

Addressed the latest MauiBot [major] finding on leak-fixer.md.

Finding: the maintainer re-open guard fetched the issue timeline with a || echo '[]' fallback. On any timeline fetch/parse failure it wrote an empty timeline → REOPENED_AT empty → the re-open override did not fire → the destructive close-issue/rebuild path ran. Net effect: a maintainer who deliberately re-opened a [leak-scan] issue would see it auto-re-closed every 6h with a false "already fixed" comment.

Fix (fail closed on the destructive path): REOPENED_AT is now computed only when the timeline is both fetched successfully and parses as a JSON array (gh api ... && jq -e 'type == "array"'). On any failure the guard writes the override sentinel, so close-issue/rebuild is skipped and the issue is left open. A distinct skip reason (re-open guard unverified (timeline lookup failed)) is emitted for the fail-closed case vs. a genuine maintainer override. The merged-[leak-fix]-PR provenance gate and bare-same-repo-ref invariants are preserved.

Empirically verified all four timeline scenarios before committing:

Scenario Before After
timeline API failure close proceeds (bug) skip close (fail closed)
non-array garbage close proceeds (bug) skip close (fail closed)
genuine maintainer re-open after merge skip close skip close (unchanged)
normal timeline, no re-open close proceeds close proceeds (unchanged)

Recompiled leak-fixer.lock.yml with gh aw v0.80.9 — body_hash only; frontmatter_hash and actions-lock.json unchanged.

cc @PureWeen


🔍 AI-generated summary (GitHub Copilot CLI, on behalf of @kubaflo).

@kubaflo

This comment has been minimized.

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

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/leak-fixer.md
Comment thread .github/workflows/leak-fixer.md
Comment thread .github/workflows/leak-fixer.md

@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

@kubaflo — new AI review results are available based on this last commit: ecda5f4. To request a fresh review after new comments or commits, comment /review rerun.

Gate No Tests Confidence Low Platform Workflow Automation Only


🗂️ 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

Issue: N/A - PR does not expose a linked issue in the local checkout; GitHub API access was unavailable.
PR: #36524 - Memory leak workflow de-dup / fixer loop prevention (inferred from local squashed diff)
Platforms Affected: workflow automation only; Android requested for testing but no Android product/runtime path is modified.
Files Changed: 4 implementation/workflow, 0 test

Key Findings

  • GitHub CLI/API access was unavailable (gh unauthenticated), so issue body, PR discussion, and live required checks could not be fetched; local squashed PR commit and diff were used as source of truth.
  • PR changes only gh-aw workflow markdown and generated lock files: daily-leak-hunter and leak-fixer.
  • The PR’s fix prevents repeated leak filing/rebuilding by deriving fixed-on-main provenance from merged workflow-owned [leak-fix] PRs and, in the fixer, guarded auto-closing of orphaned [leak-scan] issues.
  • Gate was pre-run and skipped because no tests were detected. No gate/content.md was created or overwritten.
  • Impacted UI test categories: none; this is workflow automation, not UI/product code.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: low
Errors: 0 | Warnings: 0 | Suggestions: 0

Key code review findings:

  • ℹ No new blocking findings found by the independent code-review sub-agent.
  • ℹ Prior major concerns about search cap warnings, title matching, and timeline fail-closed behavior appear addressed.
  • ℹ CI state remains undetermined because gh pr checks --required could not run in this environment.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #36524 Title-normalized merged [leak-fix] provenance suppresses hunter candidates and lets fixer close orphaned scan issues with a reopen/timeline guard. ⚠️ SKIPPED (Gate: no tests detected) .github/workflows/daily-leak-hunter.md, .github/workflows/daily-leak-hunter.lock.yml, .github/workflows/leak-fixer.md, .github/workflows/leak-fixer.lock.yml Original PR

🔬 Code Review — Deep Analysis

Code Review — PR #36524

Independent Assessment

What this changes: Updates two gh-aw memory leak workflows: adds merged [leak-fix] provenance de-duping to the hunter, adds fixer auto-close for orphaned [leak-scan] issues already fixed by merged workflow PRs, tightens safety gates, and changes fixer cadence to 6h.
Inferred motivation: Prevent repeated re-filing/rebuilding of leaks already fixed on main while avoiding data-lossy issue closure.

Reconciliation with PR Narrative

Author claims: Matches the current diff: 6h fixer cadence, merged-PR provenance gates, guarded close-issue, green-test no longer closes issues, lock files regenerated.
Agreement/disagreement: Agreement. The PR body’s mention of required labels is slightly less strict than current source; current source requires both agentic-workflows and perf/memory-leak 💦.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
Merged provenance search cap could silently drop older fixes MauiBot inline [major] ✅ Fixed / mitigated Current code uses --limit 1000 and warns at ceiling; remaining failure mode is bounded re-file/under-close, not destructive close.
Merged-fix title API matching too narrow MauiBot inline [moderate] ✅ Fixed Current jq titleapi normalizes first dotted chain to last two segments.
Timeline lookup failed open before closing issue MauiBot inline [major] ✅ Fixed Current Step 3 writes reopen-override.txt and skips close/rebuild when timeline fetch/parse fails.

Blast Radius Assessment

  • Runs for all instances: Yes — scheduled gh-aw workflows.
  • Startup impact: No app startup impact; workflow automation only.
  • Static/shared state: No product static state; changes affect workflow prompts/safe outputs.

CI Status

  • Required-check result: Undetermined — gh pr checks --required unavailable because gh is unauthenticated.
  • Classification: Pending/undetermined. Public API fallback shows Build Analysis in progress, maui-pr neutral, other checks mostly success/skipped.
  • Action taken: Invoked azdo-build-investigator; confidence capped low and no LGTM per skill rules.

Findings

No new ❌ Error, ⚠️ Warning, or 💡 Suggestion findings.

Failure-Mode Probing

  • Timeline API failure before close: Current code fails closed and skips destructive close.
  • Maintainer reopens after merged fix: Current code detects reopen after latest matched merge and skips close/rebuild.
  • Merged fix title has qualifier/namespace: Current titleapi handles Shell BackButtonBehavior.Command and fully qualified names.
  • More than 1000 merged fixes: Workflow warns; hunter may re-file once and fixer may under-close, but does not wrongly close unrelated issues.

Verdict: NEEDS_DISCUSSION

Confidence: low
Summary: Code review found no blocking code issues, and prior major findings appear addressed. However, CI is still pending/undetermined and gh pr checks --required could not run in this environment, so the skill rules prohibit LGTM until required checks are known.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Structured rooting_api: metadata in future [leak-fix] PR bodies, preferred over title parsing; keeps guarded close behavior. ✅ PASS (workflow compile + jq fixture + diff check) 4 workflow/lock files (+ local gh-aw action lock refresh in temp worktree) More robust matching than PR; first jq fallback failed and was fixed.
2 try-fix Non-destructive fixed-on-main quarantine: skip already-fixed scan issues but never auto-close them. ✅ PASS (workflow compile + close-output grep + diff check) 2 workflow/lock files (+ local gh-aw action lock refresh in temp worktree) Safest policy; avoids destructive cleanup but leaves manual issue cleanup debt.
PR PR #36524 Title-normalized merged [leak-fix] provenance suppresses hunter candidates and guarded fixer auto-closes orphaned scan issues. ⚠️ SKIPPED (Gate: no tests detected) 4 workflow/lock files Original PR

Cross-Pollination

Model Round New Ideas? Details
maui-expert-reviewer / gpt-5.5 1 Yes Proposed structured metadata provenance index; tested as try-fix-1.
maui-expert-reviewer / gpt-5.5 2 Yes Proposed non-destructive fixed-on-main quarantine; tested as try-fix-2.
orchestrator 2 No further high-value variants Remaining variants were minor combinations of metadata + quarantine or broader date-windowed GitHub searches; those are not meaningfully different enough for another try-fix in this environment.

Exhausted: Yes
Selected Fix: Candidate #1 — It preserves the PR's cleanup behavior while making the core provenance match less brittle through structured metadata and still passed gh-aw validation. Candidate #2 is safer but intentionally leaves orphaned issues open, so it is a policy tradeoff rather than a strictly better replacement.


📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the current description says the close-issue safe-output requires only agentic-workflows, but the actual winning fix guards closure with both agentic-workflows and perf/memory-leak 💦 and also needs the page-safe re-open guard detail.

Recommended title

Agentic Workflows: Improve memory-leak fixer cadence, de-dup, and guarded scan cleanup

Recommended description

This PR tunes the two agentic memory-leak workflows — `daily-leak-hunter` (files `[leak-scan]` issues) and `leak-fixer` (turns them into `[leak-fix]` PRs) — for cadence and to stop wasting runs re-processing leaks that are already fixed on `main`.

## 1. Fixer cadence: every 12h -> every 6h

The fixer now runs 4x/day instead of 2x, so review feedback on open `[leak-fix]` PRs (Track C) and new fixes (Track A) are picked up faster. Only the fixer cadence changes; the hunter keeps its existing every-12h cadence.

## 2. Fixer: stop rebuilding already-fixed leaks

The fixer's de-dup now considers merged workflow-owned `[leak-fix]` PRs, not just open and closed-unmerged fix PRs. This prevents the loop where a merged fix references an upstream issue instead of the `[leak-scan]` issue, leaving the scan issue open so the fixer repeatedly rebuilds MAUI from source, discovers the leak is already fixed on `main`, and skips without closing it.

- **Step 3 gate (d):** if a merged `[leak-fix]` PR already covers the same rooting `Type.Member` or references the `[leak-scan]` issue, close the `[leak-scan]` issue with an AI-attributed comment linking the merged PR instead of rebuilding. This is the only path that auto-closes a scan issue, and it is backed by workflow-owned merged-PR provenance.
- **Maintainer re-open guard:** before auto-closing, fetch the issue timeline with `gh api --paginate --slurp`, flatten all pages, and respect any `reopened` event after the newest matching merged fix. If the timeline cannot be fetched or parsed, fail closed: skip close/rebuild and leave the issue open.
- **Step 6:** when the regression test is green on unpatched `main`, record `skipped: test green on unpatched main (issue left open)`; do not close the scan issue. A single green result from a freshly-authored repro is not proof the leak is gone.
- **Step 10:** require `Fixes #<N>` to be the `[leak-scan]` issue number. Any separate upstream issue goes in an optional `Refs:` line, never as a second `Fixes:` line, so the scan issue auto-closes on merge going forward.
- **Safe output:** add `close-issue` with deterministic guards: `required-title-prefix: "[leak-scan] "` and `required-labels: [agentic-workflows, "perf/memory-leak 💦"]`. Write access remains isolated in the safe-outputs/conclusion jobs; the agent stays read-only.
- **Dry-run safety:** the close path is gated behind `dry_run`, matching Track C / Step 10. `dry_run=true` prints `DRY RUN — would close #<N>` instead of closing, so dry runs remain no-side-effect.

## 3. Hunter: don't re-file leaks already fixed on `main`

The hunter verifies against the shipped `Microsoft.Maui.Controls` 10.0.0 package, where a leak fixed on `main` can still reproduce until the fix ships. The empirical test alone cannot distinguish "still leaking" from "fixed on main but not shipped", and the old "closed issues may be re-filed" rule could recreate deliberately closed scan issues.

- **Step 2:** build a `fixed-on-main` `Type.Member` set from merged workflow-owned `[leak-fix]` PRs only, then skip filing candidates in that set. Off-contract titles with no dotted `Type.Member` keep a normalized `title:` fallback key instead of being dropped.
- **Hard Rule 5 / Step 6:** a leak fixed on `main` by a merged `[leak-fix]` PR is never re-filed. A leak whose only prior scan issue was closed with no merged fix PR may be re-filed if it still reproduces; a close reason such as `COMPLETED` is not proof that a fix landed.

## Review feedback addressed

Issue closure and re-file suppression are strictly provenance-gated. In particular, `[leak-scan]` issues closed as `COMPLETED` are not treated as fixed-on-main evidence, because a close reason records that someone closed the issue, not that a workflow-owned fix merged. The destructive close path also respects maintainer re-opens and fails closed if the timeline cannot be verified.

## Scope

Workflow automation only: `.github/workflows/daily-leak-hunter.md`, `.github/workflows/daily-leak-hunter.lock.yml`, `.github/workflows/leak-fixer.md`, and `.github/workflows/leak-fixer.lock.yml`. No MAUI product/runtime code changes and no platform-specific Android behavior changes.

## Testing

- `gh aw compile daily-leak-hunter leak-fixer --no-check-update --validate --approve`
- No Android/runtime tests apply because this changes gh-aw workflow automation only.

🏁 Report — Final Recommendation

Comparative Analysis — PR #36524

Candidates

Candidate Result Strengths Weaknesses
pr ⚠️ Gate skipped; expert review found a blocking workflow-safety issue Addresses the main loop: 6h fixer cadence, merged [leak-fix] de-dup, guarded orphaned [leak-scan] auto-close, and hunter re-file suppression from merged-fix provenance. The re-open guard uses gh api --paginate without --slurp, so paginated timelines can cause the newest reopened event to be missed and allow closing a maintainer-reopened scan issue.
pr-plus-reviewer ✅ Workflow compile/validation passed in sandbox with lock regeneration Keeps the PR's intended cleanup behavior and fixes the expert reviewer's page-safety issue by using --paginate --slurp, validating slurped page arrays, and flattening pages before computing the latest re-open timestamp. Does not add structured future provenance metadata; it still depends on normalized title extraction for same-API merged-fix matching.
try-fix-1 ✅ Workflow compile + jq fixture + diff check passed Adds structured rooting_api: metadata for future [leak-fix] PR bodies and prefers that over title parsing, making future same-API matching more durable. It does not modify the raw PR's re-open guard, so it inherits the gh api --paginate page-safety defect found by expert review.
try-fix-2 ✅ Workflow compile + close-output grep + diff check passed Safest non-destructive policy: skips already-fixed issues without any auto-close path, avoiding the re-open guard risk entirely. Drops the PR's desired automated cleanup behavior, leaving orphaned [leak-scan] issues open for manual cleanup and preserving issue-triage debt.

Ranking

  1. pr-plus-reviewer — Best balance of safety and product intent. It preserves the merged-PR de-dup/auto-close design while fixing the only expert-review blocking defect.
  2. try-fix-2 — Safe and passed validation, but intentionally weakens the desired cleanup outcome by never closing orphaned scan issues.
  3. try-fix-1 — More durable future provenance than the PR, but lower ranked because it still inherits the unsafe paginated timeline guard.
  4. pr — Implements the intended behavior, but lower ranked because the expert reviewer found a real data-loss/control-flow bug in the destructive close path.

Winner

Winner: pr-plus-reviewer

This candidate should be used because it fixes the actionable reviewer finding without giving up the PR's core behavior: already-fixed scan issues are still closed only from workflow-owned merged [leak-fix] provenance, dry-run remains side-effect free, and maintainer re-opens are respected even when the timeline is paginated.


🧭 Next Steps — review latest findings

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

@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.

Expert Review — 1 findings

See inline comments for details.

Comment thread .github/workflows/leak-fixer.md Outdated
@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 15, 2026

@PureWeen PureWeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Found one new high-confidence correctness issue in the timeline-based maintainer re-open guard.\n\nThe re-open guard is necessary, but pagination currently permits it to miss a later re-open and repeat the destructive close path.\n\n_Flagged by: 3/3 independent reviewers after direct reproduction._

Comment thread .github/workflows/leak-fixer.md Outdated

@PureWeen PureWeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Adversarial re-review\n\nNo new actionable issues found on this unchanged revision.\n\nWhat looks right: the generated lock files still runtime-import their matching workflow sources, preserving source/lock behavior.\n\nTest coverage: No tests changed; this PR modifies gh-aw workflow source and generated locks.\n\nPrior review status: All existing inline findings, including the pagination defect in the maintainer re-open guard, were excluded from this pass. The two newly proposed concerns were rejected after adversarial validation.\n\n_Methodology: 3 independent reviewers with adversarial consensus._

@PureWeen PureWeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Adversarial re-review\n\nNo new actionable issues found on this unchanged revision.\n\nWhat looks right: the compiled close_issue path validates every configured required label before executing, matching the source workflow’s dual-label constraint.\n\nTest coverage: No tests changed; this PR modifies gh-aw workflow source and generated locks.\n\nPrior review status: Earlier inline findings, including the multi-page re-open-timeline defect, were excluded from this pass.\n\n_Methodology: 3 independent reviewers with adversarial consensus._

@PureWeen PureWeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No additional actionable findings in this pass.

  • The authoritative four-file diff at ecda5f43 was reviewed; the generated locks remain aligned with their matching gh-aw sources.
  • Existing review feedback remains the source of any outstanding work; this unchanged head introduces no separate issue to add.
  • Test coverage: this is workflow prompt/configuration work with no changed test path.

Methodology: 3 independent reviewers with adversarial consensus.

Comment thread .github/workflows/leak-fixer.md

@PureWeen PureWeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

⚠️ Logic — The new re-open-override sentinel can leak from one auto-selected scan issue into the next candidate evaluated during the same run, suppressing unrelated fix work.

  • 3/3 reviewers after dispute: scope or reset reopen-override.txt for each candidate before using its existence as a gate.
  • Prior review status: the author acknowledged the existing timeline-pagination finding; it remains separate and unaddressed on this head.
  • Test coverage: workflow prompt/configuration change; no test path changed.

Methodology: 3 independent reviewers with adversarial consensus.

…entinel

Two review fixes for the maintainer re-open guard:

- Merge paginated timeline pages before testing the override. 'gh api
  --paginate' writes each page as a SEPARATE JSON array, so a multi-page
  timeline emitted concatenated arrays and the jq reads ran once per page —
  REOPENED_AT could become multi-valued and the override comparison misfire.
  Fetch with --slurp and flatten the array-of-arrays with 'jq add // []' into
  a single event stream (also makes the 'type == array' guard robust).

- Reset the shared reopen-override.txt sentinel at the start of each candidate.
  It is a single fixed path (not keyed by $N) written only inside the
  merged-fix block, while Step 3 may advance to the next-oldest candidate in
  the same run. Without the reset a sentinel written for an earlier candidate
  leaked forward and falsely gated a later one. rm -f it per candidate.

Recompiled leak-fixer.lock.yml (body_hash only).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d00747b7-96f3-4e7a-8dfb-e3a48db04b2d
Copilot AI review requested due to automatic review settings July 21, 2026 14:43
@kubaflo

kubaflo commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator Author

@PureWeen addressed both remaining review findings (pushed 56abf8da, leak-fixer.lock.yml recompiled — body_hash only):

  • High: merge paginated timeline before the override test — the timeline is now fetched with --paginate --slurp and flattened via jq 'add // []' into a single event stream, so a >1-page timeline no longer runs the jq reads per page (which made REOPENED_AT multi-valued). API errors still short-circuit to the fail-closed else.
  • Logic: shared reopen-override.txt — now rm -f'd at the start of every candidate (unconditionally, before the merged-fix block), so a sentinel written for an earlier candidate can't leak forward and falsely gate a later one in the same run.

Ready for re-review — thanks!

🔍 AI-generated comment on @kubaflo's behalf.

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@kubaflo

This comment has been minimized.

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

MauiBot commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

⚠️ Merge Conflict Detected — This PR has merge conflicts with its target branch. Please rebase onto the target branch and resolve the conflicts.

@MauiBot

MauiBot commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Warning

🔍 Automated review could not complete

A stage of the reviewer pipeline could not finish, so no review summary was produced for this run — most often the review stage itself hanging, or the run being canceled by its overall timeout. This is almost always a transient infrastructure issue on the CI agent, not a problem with your PR. (Note: a test-verification gate timeout no longer lands here — it now posts a normal AI Summary whose Gate section explains the timeout.)

Please re-comment /review to retry on a fresh agent.

🔍 Automated message from the .NET MAUI Copilot reviewer pipeline · build log

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ai-agents Copilot CLI agents, agent skills, AI-assisted development area-infrastructure CI, Maestro / Coherency, upstream dependencies/versions s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates 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.

5 participants