diff --git a/.github/agents/agentic-workflows.agent.md b/.github/agents/agentic-workflows.agent.md
index 90032e74d83..7532f4e39ee 100644
--- a/.github/agents/agentic-workflows.agent.md
+++ b/.github/agents/agentic-workflows.agent.md
@@ -1,6 +1,6 @@
 ---
 description: GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade AI-powered workflows with intelligent prompt routing
-infer: false
+disable-model-invocation: true
 ---
 
 # GitHub Agentic Workflows Agent
@@ -15,7 +15,10 @@ This is a **dispatcher agent** that routes your request to the appropriate speci
 - **Updating existing workflows**: Routes to `update` prompt
 - **Debugging workflows**: Routes to `debug` prompt  
 - **Upgrading workflows**: Routes to `upgrade-agentic-workflows` prompt
+- **Creating report-generating workflows**: Routes to `report` prompt — consult this whenever the workflow posts status updates, audits, analyses, or any structured output as issues, discussions, or comments
 - **Creating shared components**: Routes to `create-shared-agentic-workflow` prompt
+- **Fixing Dependabot PRs**: Routes to `dependabot` prompt — use this when Dependabot opens PRs that modify generated manifest files (`.github/workflows/package.json`, `.github/workflows/requirements.txt`, `.github/workflows/go.mod`). Never merge those PRs directly; instead update the source `.md` files and rerun `gh aw compile --dependabot` to bundle all fixes
+- **Analyzing test coverage**: Routes to `test-coverage` prompt — consult this whenever the workflow reads, analyzes, or reports on test coverage data from PRs or CI runs
 
 Workflows may optionally include:
 
@@ -27,7 +30,7 @@ Workflows may optionally include:
 - Workflow files: `.github/workflows/*.md` and `.github/workflows/**/*.md`
 - Workflow lock files: `.github/workflows/*.lock.yml`
 - Shared components: `.github/workflows/shared/*.md`
-- Configuration: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/github-agentic-workflows.md
+- Configuration: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/github-agentic-workflows.md
 
 ## Problems This Solves
 
@@ -49,7 +52,7 @@ When you interact with this agent, it will:
 ### Create New Workflow
 **Load when**: User wants to create a new workflow from scratch, add automation, or design a workflow that doesn't exist yet
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/create-agentic-workflow.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/create-agentic-workflow.md
 
 **Use cases**:
 - "Create a workflow that triages issues"
@@ -59,7 +62,7 @@ When you interact with this agent, it will:
 ### Update Existing Workflow  
 **Load when**: User wants to modify, improve, or refactor an existing workflow
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/update-agentic-workflow.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/update-agentic-workflow.md
 
 **Use cases**:
 - "Add web-fetch tool to the issue-classifier workflow"
@@ -69,7 +72,7 @@ When you interact with this agent, it will:
 ### Debug Workflow  
 **Load when**: User needs to investigate, audit, debug, or understand a workflow, troubleshoot issues, analyze logs, or fix errors
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/debug-agentic-workflow.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/debug-agentic-workflow.md
 
 **Use cases**:
 - "Why is this workflow failing?"
@@ -79,46 +82,52 @@ When you interact with this agent, it will:
 ### Upgrade Agentic Workflows
 **Load when**: User wants to upgrade workflows to a new gh-aw version or fix deprecations
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/upgrade-agentic-workflows.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/upgrade-agentic-workflows.md
 
 **Use cases**:
 - "Upgrade all workflows to the latest version"
 - "Fix deprecated fields in workflows"
 - "Apply breaking changes from the new release"
 
+### Create a Report-Generating Workflow
+**Load when**: The workflow being created or updated produces reports — recurring status updates, audit summaries, analyses, or any structured output posted as a GitHub issue, discussion, or comment
+
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/report.md
+
+**Use cases**:
+- "Create a weekly CI health report"
+- "Post a daily security audit to Discussions"
+- "Add a status update comment to open PRs"
+
 ### Create Shared Agentic Workflow
 **Load when**: User wants to create a reusable workflow component or wrap an MCP server
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/create-shared-agentic-workflow.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/create-shared-agentic-workflow.md
 
 **Use cases**:
 - "Create a shared component for Notion integration"
 - "Wrap the Slack MCP server as a reusable component"
 - "Design a shared workflow for database queries"
 
-### Orchestration and Delegation
-
-**Load when**: Creating or updating workflows that coordinate multiple agents or dispatch work to other workflows
+### Fix Dependabot PRs
+**Load when**: User needs to close or fix open Dependabot PRs that update dependencies in generated manifest files (`.github/workflows/package.json`, `.github/workflows/requirements.txt`, `.github/workflows/go.mod`)
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/orchestration.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/dependabot.md
 
 **Use cases**:
-- Assigning work to AI coding agents
-- Dispatching specialized worker workflows
-- Using correlation IDs for tracking
-- Orchestration design patterns
-
-### GitHub Projects Integration
+- "Fix the open Dependabot PRs for npm dependencies"
+- "Bundle and close the Dependabot PRs for workflow dependencies"
+- "Update @playwright/test to fix the Dependabot PR"
 
-**Load when**: Creating or updating workflows that manage GitHub Projects v2
+### Analyze Test Coverage
+**Load when**: The workflow reads, analyzes, or reports test coverage — whether triggered by a PR, a schedule, or a slash command. Always consult this prompt before designing the coverage data strategy.
 
-**Prompt file**: https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/projects.md
+**Prompt file**: https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/test-coverage.md
 
 **Use cases**:
-- Tracking items and fields with update-project
-- Posting periodic run summaries
-- Creating new projects
-- Projects v2 authentication and configuration
+- "Create a workflow that comments coverage on PRs"
+- "Analyze coverage trends over time"
+- "Add a coverage gate that blocks PRs below a threshold"
 
 ## Instructions
 
@@ -160,8 +169,10 @@ gh aw compile --validate
 
 ## Important Notes
 
-- Always reference the instructions file at https://github.com/github/gh-aw/blob/v0.45.0/.github/aw/github-agentic-workflows.md for complete documentation
+- Always reference the instructions file at https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/github-agentic-workflows.md for complete documentation
 - Use the MCP tool `agentic-workflows` when running in GitHub Copilot Cloud
 - Workflows must be compiled to `.lock.yml` files before running in GitHub Actions
 - **Bash tools are enabled by default** - Don't restrict bash commands unnecessarily since workflows are sandboxed by the AWF
 - Follow security best practices: minimal permissions, explicit network access, no template injection
+- **Network configuration**: Use ecosystem identifiers (`node`, `python`, `go`, etc.) or explicit FQDNs in `network.allowed`. Bare shorthands like `npm` or `pypi` are **not** valid. See https://github.com/github/gh-aw/blob/v0.67.1/.github/aw/network.md for the full list of valid ecosystem identifiers and domain patterns.
+- **Single-file output**: When creating a workflow, produce exactly **one** workflow `.md` file. Do not create separate documentation files (architecture docs, runbooks, usage guides, etc.). If documentation is needed, add a brief `## Usage` section inside the workflow file itself.
diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json
index 3919d9a7d83..a861762c663 100644
--- a/.github/aw/actions-lock.json
+++ b/.github/aw/actions-lock.json
@@ -5,15 +5,20 @@
       "version": "v8",
       "sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd"
     },
-    "github/gh-aw-actions/setup@v0.62.0": {
+    "github/gh-aw-actions/setup@v0.67.1": {
       "repo": "github/gh-aw-actions/setup",
-      "version": "v0.62.0",
-      "sha": "b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6"
+      "version": "v0.67.1",
+      "sha": "80471a493be8c528dd27daf73cd644242a7965e0"
     },
-    "github/gh-aw/actions/setup@v0.62.0": {
+    "github/gh-aw-actions/setup@v0.67.2": {
+      "repo": "github/gh-aw-actions/setup",
+      "version": "v0.67.2",
+      "sha": "03e31e064a68e8d5ad890c92f303cfb5a3536006"
+    },
+    "github/gh-aw/actions/setup@v0.67.2": {
       "repo": "github/gh-aw/actions/setup",
-      "version": "v0.62.0",
-      "sha": "f1633bcc50ad7480f44d25961863c36fadd787ec"
+      "version": "v0.67.2",
+      "sha": "5fb582bad4dfee2841251e97f9d22caa7eb3c82d"
     }
   }
 }
diff --git a/.github/instructions/ComponentTests.instructions.md b/.github/instructions/ComponentTests.instructions.md
new file mode 100644
index 00000000000..ecca1507aee
--- /dev/null
+++ b/.github/instructions/ComponentTests.instructions.md
@@ -0,0 +1,132 @@
+---
+applyTo:
+  - "tests/FSharp.Compiler.ComponentTests/**/*.fs"
+---
+
+# ComponentTests DSL
+
+Tests use a pipeline: **Create → Configure → Action → Assert**. The action verb is mandatory — never pipe a `CompilationUnit` directly into an assertion.
+
+## Actions (pick the cheapest that covers what you're testing)
+
+```fsharp
+// Type errors only, no codegen — fastest
+FSharp "..."
+|> typecheck
+|> shouldSucceed
+
+// Full compile, produces assembly
+FSharp "..."
+|> compile
+|> shouldSucceed
+
+// IL shape verification (needs compile)
+FSharp "..."
+|> compile
+|> verifyILContains [".method"]
+
+// Compile + execute (needs EntryPoint and asExe)
+FSharp "..."
+|> compileExeAndRun
+|> shouldSucceed
+
+// FSI in-process
+Fsx "..."
+|> eval
+|> withEvalValueEquals 2
+
+// FSI subprocess
+Fsx "..."
+|> runFsi
+|> withStdOutContains "hello"
+```
+
+Use `typecheck` for anything that doesn't need IL or runtime. Use `compile` only when you need the assembly (IL checks, interop). Use `compileExeAndRun` only when testing runtime behavior.
+
+## Diagnostics
+
+```fsharp
+// Exact diagnostic with location and message
+FSharp "..."
+|> typecheck
+|> shouldFail
+|> withDiagnostics [
+    (Error 73, Line 3, Col 5, Line 3, Col 10, "internal error: ...")
+    (Warning 20, Line 5, Col 1, Line 5, Col 8, "The result of this expression...")
+]
+
+// Just error code (when message/location don't matter)
+FSharp "..."
+|> typecheck
+|> shouldFail
+|> withErrorCode 73
+```
+
+## C# interop
+
+```fsharp
+let csLib =
+    CSharp """public interface I { void M(out int v); }"""
+    |> withName "CsLib"
+
+FSharp """
+open CsLib
+type T() = interface I with member _.M(v) = v <- 42
+"""
+|> withReferences [csLib]
+|> compile
+|> shouldSucceed
+```
+
+## Regression test template
+
+```fsharp
+// https://github.com/dotnet/fsharp/issues/NNNNN
+[<Fact>]
+let ``Issue NNNNN - brief description`` () =
+    FSharp """
+// minimal repro from issue
+    """
+    |> asLibrary
+    |> typecheck
+    |> shouldSucceed
+```
+
+## Local helpers
+
+If configuration becomes long and boilerplate, extract a local helper or use an existing one in the same module:
+
+```fsharp
+// Local helper for repeated configuration
+let typecheckWithPreview source =
+    source
+    |> asLibrary
+    |> withLangVersionPreview
+    |> withOptions ["--test:ErrorRanges"]
+    |> typecheck
+
+// Usage
+FSharp "..."
+|> typecheckWithPreview
+|> shouldSucceed
+```
+
+## Common mistakes
+
+- Missing action: `FSharp "..." |> shouldSucceed` — won't compile, `shouldSucceed` expects `CompilationResult`
+- Missing `asExe` for runtime tests: `FSharp "..." |> compile |> run` fails on library output
+- Using `compile` when `typecheck` suffices — wastes CI time
+
+## Platform attributes
+
+Use `[<Fact>]` unless the test requires a specific runtime:
+- `[<FactForNETCOREAPP>]` — .NET Core only
+- `[<FactForDESKTOP>]` — .NET Framework only
+- `[<FactForWINDOWS>]` — Windows only
+
+## Workflow
+
+1. Write test with explicit pipeline
+2. Build: `dotnet build tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj -c Release`
+3. Run: `dotnet test --project tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj -c Release --no-build -- --filter-method "*TestName*"`
+4. Format: `dotnet fantomas <file.fs>`
diff --git a/.github/skills/fsharp-diagnostics/SKILL.md b/.github/skills/fsharp-diagnostics/SKILL.md
index 76b1b2808c2..846303abe6d 100644
--- a/.github/skills/fsharp-diagnostics/SKILL.md
+++ b/.github/skills/fsharp-diagnostics/SKILL.md
@@ -1,6 +1,6 @@
 ---
 name: fsharp-diagnostics
-description: "After modifying any F# file, use this to get quick parse errors and typecheck warnings+errors. Also finds symbol references and inferred type hints."
+description: "Always invoke after editing .fs files. Provides fast parse/typecheck feedback without a full dotnet build. Prefer this over dotnet build for iterative changes. Also finds symbol references and inferred type hints."
 ---
 
 # F# Diagnostics
diff --git a/.github/workflows/aw-auto-update.lock.yml b/.github/workflows/aw-auto-update.lock.yml
new file mode 100644
index 00000000000..a4703cca3f8
--- /dev/null
+++ b/.github/workflows/aw-auto-update.lock.yml
@@ -0,0 +1,1203 @@
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"cee3cbbc17a8d1be9fcf671400323b7e1b15d416cb0ec65fbdb6f441e0e9a1a9","compiler_version":"v0.67.1","strict":true,"agent_id":"copilot"}
+#    ___                   _   _      
+#   / _ \                 | | (_)     
+#  | |_| | __ _  ___ _ __ | |_ _  ___ 
+#  |  _  |/ _` |/ _ \ '_ \| __| |/ __|
+#  | | | | (_| |  __/ | | | |_| | (__ 
+#  \_| |_/\__, |\___|_| |_|\__|_|\___|
+#          __/ |
+#  _    _ |___/ 
+# | |  | |                / _| |
+# | |  | | ___ _ __ _  __| |_| | _____      ____
+# | |/\| |/ _ \ '__| |/ /|  _| |/ _ \ \ /\ / / ___|
+# \  /\  / (_) | | | | ( | | | | (_) \ V  V /\__ \
+#  \/  \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw (v0.67.1). DO NOT EDIT.
+#
+# To update this file, edit the corresponding .md file and run:
+#   gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# Keeps agentic workflows up to date by running `gh aw upgrade` and `gh aw compile` daily.
+# If changes are detected, pushes them to a long-lived branch and creates or updates a PR.
+#
+# Secrets used:
+#   - COPILOT_GITHUB_TOKEN
+#   - GH_AW_CI_TRIGGER_TOKEN
+#   - GH_AW_GITHUB_MCP_SERVER_TOKEN
+#   - GH_AW_GITHUB_TOKEN
+#   - GITHUB_TOKEN
+#
+# Custom actions used:
+#   - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+#   - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+#   - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+#   - actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+#   - github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+
+name: "Agentic Workflow Auto-Update"
+"on":
+  schedule:
+  - cron: "52 */24 * * *"
+    # Friendly format: every 24h (scattered)
+  workflow_dispatch:
+    inputs:
+      aw_context:
+        default: ""
+        description: Agent caller context (used internally by Agentic Workflows).
+        required: false
+        type: string
+
+permissions: {}
+
+concurrency:
+  group: "gh-aw-${{ github.workflow }}"
+
+run-name: "Agentic Workflow Auto-Update"
+
+jobs:
+  activation:
+    runs-on: ubuntu-slim
+    permissions:
+      contents: read
+    outputs:
+      comment_id: ""
+      comment_repo: ""
+      lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+      model: ${{ steps.generate_aw_info.outputs.model }}
+      secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+      - name: Generate agentic run info
+        id: generate_aw_info
+        env:
+          GH_AW_INFO_ENGINE_ID: "copilot"
+          GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
+          GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }}
+          GH_AW_INFO_VERSION: "latest"
+          GH_AW_INFO_AGENT_VERSION: "latest"
+          GH_AW_INFO_CLI_VERSION: "v0.67.1"
+          GH_AW_INFO_WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+          GH_AW_INFO_EXPERIMENTAL: "false"
+          GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+          GH_AW_INFO_STAGED: "false"
+          GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
+          GH_AW_INFO_FIREWALL_ENABLED: "true"
+          GH_AW_INFO_AWF_VERSION: "v0.25.13"
+          GH_AW_INFO_AWMG_VERSION: ""
+          GH_AW_INFO_FIREWALL_TYPE: "squid"
+          GH_AW_COMPILED_STRICT: "true"
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
+            await main(core, context);
+      - name: Validate COPILOT_GITHUB_TOKEN secret
+        id: validate-secret
+        run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
+        env:
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+      - name: Checkout .github and .agents folders
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+          sparse-checkout: |
+            .github
+            .agents
+          sparse-checkout-cone-mode: true
+          fetch-depth: 1
+      - name: Check workflow lock file
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_WORKFLOW_FILE: "aw-auto-update.lock.yml"
+          GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
+            await main();
+      - name: Check compile-agentic version
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_COMPILED_VERSION: "v0.67.1"
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
+            await main();
+      - name: Create prompt with built-in context
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
+          GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+          GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
+          GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
+          GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+          GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+          GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+          GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+          GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+        # poutine:ignore untrusted_checkout_exec
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
+          {
+          cat << 'GH_AW_PROMPT_129f48edee93c656_EOF'
+          <system>
+          GH_AW_PROMPT_129f48edee93c656_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
+          cat << 'GH_AW_PROMPT_129f48edee93c656_EOF'
+          <safe-output-tools>
+          Tools: create_pull_request, push_to_pull_request_branch, missing_tool, missing_data, noop
+          GH_AW_PROMPT_129f48edee93c656_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
+          cat << 'GH_AW_PROMPT_129f48edee93c656_EOF'
+          </safe-output-tools>
+          <github-context>
+          The following GitHub context information is available for this workflow:
+          {{#if __GH_AW_GITHUB_ACTOR__ }}
+          - **actor**: __GH_AW_GITHUB_ACTOR__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_REPOSITORY__ }}
+          - **repository**: __GH_AW_GITHUB_REPOSITORY__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_WORKSPACE__ }}
+          - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
+          - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
+          - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
+          - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
+          - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_RUN_ID__ }}
+          - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+          {{/if}}
+          - **checkouts**: The following repositories have been checked out and are available in the workspace:
+            - `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) [shallow clone, fetch-depth=1 (default)]
+            - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
+          </github-context>
+          
+          GH_AW_PROMPT_129f48edee93c656_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+          cat << 'GH_AW_PROMPT_129f48edee93c656_EOF'
+          </system>
+          {{#runtime-import .github/workflows/aw-auto-update.md}}
+          GH_AW_PROMPT_129f48edee93c656_EOF
+          } > "$GH_AW_PROMPT"
+      - name: Interpolate variables and render templates
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
+            await main();
+      - name: Substitute placeholders
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+          GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
+          GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
+          GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+          GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+          GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+          GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+          GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            
+            const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
+            
+            // Call the substitution function
+            return await substitutePlaceholders({
+              file: process.env.GH_AW_PROMPT,
+              substitutions: {
+                GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+                GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
+                GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
+                GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
+                GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
+                GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
+                GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
+                GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE
+              }
+            });
+      - name: Validate prompt placeholders
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        # poutine:ignore untrusted_checkout_exec
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
+      - name: Print prompt
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        # poutine:ignore untrusted_checkout_exec
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
+      - name: Upload activation artifact
+        if: success()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: activation
+          path: |
+            /tmp/gh-aw/aw_info.json
+            /tmp/gh-aw/aw-prompts/prompt.txt
+            /tmp/gh-aw/github_rate_limits.jsonl
+          if-no-files-found: ignore
+          retention-days: 1
+
+  agent:
+    needs: activation
+    runs-on: ubuntu-latest
+    permissions: read-all
+    concurrency:
+      group: "gh-aw-copilot-${{ github.workflow }}"
+    env:
+      DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
+      GH_AW_ASSETS_ALLOWED_EXTS: ""
+      GH_AW_ASSETS_BRANCH: ""
+      GH_AW_ASSETS_MAX_SIZE_KB: 0
+      GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+      GH_AW_WORKFLOW_ID_SANITIZED: awautoupdate
+    outputs:
+      checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
+      effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
+      has_patch: ${{ steps.collect_output.outputs.has_patch }}
+      inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
+      model: ${{ needs.activation.outputs.model }}
+      output: ${{ steps.collect_output.outputs.output }}
+      output_types: ${{ steps.collect_output.outputs.output_types }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Set runtime paths
+        id: set-runtime-paths
+        run: |
+          echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_OUTPUT"
+          echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_OUTPUT"
+          echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_OUTPUT"
+      - name: Checkout repository
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+          ref: main
+      - name: Create gh-aw temp directory
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
+      - name: Configure gh CLI for GitHub Enterprise
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
+        env:
+          GH_TOKEN: ${{ github.token }}
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Checkout PR branch
+        id: checkout-pr
+        if: |
+          github.event.pull_request || github.event.issue.pull_request
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
+            await main();
+      - name: Install GitHub Copilot CLI
+        run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
+        env:
+          GH_HOST: github.com
+      - name: Install AWF binary
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13
+      - name: Parse integrity filter lists
+        id: parse-guard-vars
+        env:
+          GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+          GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+          GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh
+      - name: Download container images
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.14 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
+      - name: Write Safe Outputs Config
+        run: |
+          mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
+          mkdir -p /tmp/gh-aw/safeoutputs
+          mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_52bfaaa26afe65fd_EOF'
+          {"create_pull_request":{"draft":false,"labels":["automation"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_path_prefixes":[".github/",".agents/"],"title_prefix":"[Auto Update] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"if_no_changes":"warn","labels":["automation"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_path_prefixes":[".github/",".agents/"],"target":"*","title_prefix":"[Auto Update] "},"report_incomplete":{}}
+          GH_AW_SAFE_OUTPUTS_CONFIG_52bfaaa26afe65fd_EOF
+      - name: Write Safe Outputs Tools
+        run: |
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_77928e152c9bfecb_EOF'
+          {
+            "description_suffixes": {
+              "create_pull_request": " CONSTRAINTS: Maximum 1 pull request(s) can be created. Title will be prefixed with \"[Auto Update] \". Labels [\"automation\"] will be automatically added.",
+              "push_to_pull_request_branch": " CONSTRAINTS: Maximum 1 push(es) can be made. The target pull request title must start with \"[Auto Update] \"."
+            },
+            "repo_params": {},
+            "dynamic_tools": []
+          }
+          GH_AW_SAFE_OUTPUTS_TOOLS_META_77928e152c9bfecb_EOF
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_2d02a88b923d571f_EOF'
+          {
+            "create_pull_request": {
+              "defaultMax": 1,
+              "fields": {
+                "body": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "branch": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "draft": {
+                  "type": "boolean"
+                },
+                "labels": {
+                  "type": "array",
+                  "itemType": "string",
+                  "itemSanitize": true,
+                  "itemMaxLength": 128
+                },
+                "repo": {
+                  "type": "string",
+                  "maxLength": 256
+                },
+                "title": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                }
+              }
+            },
+            "missing_data": {
+              "defaultMax": 20,
+              "fields": {
+                "alternatives": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "context": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "data_type": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                },
+                "reason": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                }
+              }
+            },
+            "missing_tool": {
+              "defaultMax": 20,
+              "fields": {
+                "alternatives": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 512
+                },
+                "reason": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "tool": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                }
+              }
+            },
+            "noop": {
+              "defaultMax": 1,
+              "fields": {
+                "message": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                }
+              }
+            },
+            "push_to_pull_request_branch": {
+              "defaultMax": 1,
+              "fields": {
+                "branch": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "message": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "pull_request_number": {
+                  "issueOrPRNumber": true
+                }
+              }
+            },
+            "report_incomplete": {
+              "defaultMax": 5,
+              "fields": {
+                "details": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "reason": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 1024
+                }
+              }
+            }
+          }
+          GH_AW_SAFE_OUTPUTS_VALIDATION_2d02a88b923d571f_EOF
+          node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
+      - name: Generate Safe Outputs MCP Server Config
+        id: safe-outputs-config
+        run: |
+          # Generate a secure random API key (360 bits of entropy, 40+ chars)
+          # Mask immediately to prevent timing vulnerabilities
+          API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+          echo "::add-mask::${API_KEY}"
+          
+          PORT=3001
+          
+          # Set outputs for next steps
+          {
+            echo "safe_outputs_api_key=${API_KEY}"
+            echo "safe_outputs_port=${PORT}"
+          } >> "$GITHUB_OUTPUT"
+          
+          echo "Safe Outputs MCP server will run on port ${PORT}"
+          
+      - name: Start Safe Outputs MCP HTTP Server
+        id: safe-outputs-start
+        env:
+          DEBUG: '*'
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
+          GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
+          GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
+          GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
+          GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+        run: |
+          # Environment variables are set above to prevent template injection
+          export DEBUG
+          export GH_AW_SAFE_OUTPUTS
+          export GH_AW_SAFE_OUTPUTS_PORT
+          export GH_AW_SAFE_OUTPUTS_API_KEY
+          export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
+          export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
+          export GH_AW_MCP_LOG_DIR
+          
+          bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh
+          
+      - name: Start MCP Gateway
+        id: start-mcp-gateway
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
+          GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+          GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          set -eo pipefail
+          mkdir -p /tmp/gh-aw/mcp-config
+          
+          # Export gateway environment variables for MCP config and gateway script
+          export MCP_GATEWAY_PORT="80"
+          export MCP_GATEWAY_DOMAIN="host.docker.internal"
+          MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+          echo "::add-mask::${MCP_GATEWAY_API_KEY}"
+          export MCP_GATEWAY_API_KEY
+          export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
+          mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
+          export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
+          export DEBUG="*"
+          
+          export GH_AW_ENGINE="copilot"
+          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.14'
+          
+          mkdir -p /home/runner/.copilot
+          cat << GH_AW_MCP_CONFIG_4027a72012fb469c_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
+          {
+            "mcpServers": {
+              "github": {
+                "type": "stdio",
+                "container": "ghcr.io/github/github-mcp-server:v0.32.0",
+                "env": {
+                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
+                  "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
+                  "GITHUB_READ_ONLY": "1",
+                  "GITHUB_TOOLSETS": "pull_requests"
+                },
+                "guard-policies": {
+                  "allow-only": {
+                    "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+                    "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+                    "min-integrity": "none",
+                    "repos": "all",
+                    "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
+                  }
+                }
+              },
+              "safeoutputs": {
+                "type": "http",
+                "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
+                "headers": {
+                  "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+                },
+                "guard-policies": {
+                  "write-sink": {
+                    "accept": [
+                      "*"
+                    ]
+                  }
+                }
+              }
+            },
+            "gateway": {
+              "port": $MCP_GATEWAY_PORT,
+              "domain": "${MCP_GATEWAY_DOMAIN}",
+              "apiKey": "${MCP_GATEWAY_API_KEY}",
+              "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
+            }
+          }
+          GH_AW_MCP_CONFIG_4027a72012fb469c_EOF
+      - name: Download activation artifact
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: activation
+          path: /tmp/gh-aw
+      - name: Clean git credentials
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh
+      - name: Execute GitHub Copilot CLI
+        id: agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        timeout-minutes: 15
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
+          GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
+          GH_AW_PHASE: agent
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_VERSION: v0.67.1
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Detect inference access error
+        id: detect-inference-error
+        if: always()
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Copy Copilot session state files to logs
+        if: always()
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh
+      - name: Stop MCP Gateway
+        if: always()
+        continue-on-error: true
+        env:
+          MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+          MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+          GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID"
+      - name: Redact secrets in logs
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
+            await main();
+        env:
+          GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+          SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+          SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+          SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      - name: Append agent step summary
+        if: always()
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
+      - name: Copy Safe Outputs
+        if: always()
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+        run: |
+          mkdir -p /tmp/gh-aw
+          cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
+      - name: Ingest agent output
+        id: collect_output
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_API_URL: ${{ github.api_url }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
+            await main();
+      - name: Parse agent logs for step summary
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
+            await main();
+      - name: Parse MCP Gateway logs for step summary
+        if: always()
+        id: parse-mcp-gateway
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
+            await main();
+      - name: Print firewall logs
+        if: always()
+        continue-on-error: true
+        env:
+          AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
+        run: |
+          # Fix permissions on firewall logs so they can be uploaded as artifacts
+          # AWF runs with sudo, creating files owned by root
+          sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
+          # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
+          if command -v awf &> /dev/null; then
+            awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
+          else
+            echo 'AWF binary not installed, skipping firewall log summary'
+          fi
+      - name: Parse token usage for step summary
+        if: always()
+        continue-on-error: true
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
+            await main();
+      - name: Write agent output placeholder if missing
+        if: always()
+        run: |
+          if [ ! -f /tmp/gh-aw/agent_output.json ]; then
+            echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
+          fi
+      - name: Upload agent artifacts
+        if: always()
+        continue-on-error: true
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: agent
+          path: |
+            /tmp/gh-aw/aw-prompts/prompt.txt
+            /tmp/gh-aw/sandbox/agent/logs/
+            /tmp/gh-aw/redacted-urls.log
+            /tmp/gh-aw/mcp-logs/
+            /tmp/gh-aw/proxy-logs/
+            !/tmp/gh-aw/proxy-logs/proxy-tls/
+            /tmp/gh-aw/agent_usage.json
+            /tmp/gh-aw/agent-stdio.log
+            /tmp/gh-aw/agent/
+            /tmp/gh-aw/github_rate_limits.jsonl
+            /tmp/gh-aw/safeoutputs.jsonl
+            /tmp/gh-aw/agent_output.json
+            /tmp/gh-aw/aw-*.patch
+            /tmp/gh-aw/aw-*.bundle
+          if-no-files-found: ignore
+      - name: Upload firewall audit logs
+        if: always()
+        continue-on-error: true
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: firewall-audit-logs
+          path: |
+            /tmp/gh-aw/sandbox/firewall/logs/
+            /tmp/gh-aw/sandbox/firewall/audit/
+          if-no-files-found: ignore
+
+  conclusion:
+    needs:
+      - activation
+      - agent
+      - detection
+      - safe_outputs
+    if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+      issues: write
+      pull-requests: write
+    concurrency:
+      group: "gh-aw-conclusion-aw-auto-update"
+      cancel-in-progress: false
+    outputs:
+      incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
+      noop_message: ${{ steps.noop.outputs.noop_message }}
+      tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
+      total_count: ${{ steps.missing_tool.outputs.total_count }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Process No-Op Messages
+        id: noop
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_NOOP_MAX: "1"
+          GH_AW_WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_NOOP_REPORT_AS_ISSUE: "true"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
+            await main();
+      - name: Record Missing Tool
+        id: missing_tool
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
+          GH_AW_WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
+            await main();
+      - name: Record Incomplete
+        id: report_incomplete
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
+          GH_AW_WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
+            await main();
+      - name: Handle Agent Failure
+        id: handle_agent_failure
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_WORKFLOW_ID: "aw-auto-update"
+          GH_AW_ENGINE_ID: "copilot"
+          GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
+          GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+          GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+          GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
+          GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
+          GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+          GH_AW_GROUP_REPORTS: "false"
+          GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+          GH_AW_TIMEOUT_MINUTES: "15"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
+            await main();
+
+  detection:
+    needs:
+      - activation
+      - agent
+    if: >
+      always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+    outputs:
+      detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+      detection_success: ${{ steps.detection_conclusion.outputs.success }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Checkout repository for patch context
+        if: needs.agent.outputs.has_patch == 'true'
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+      # --- Threat Detection ---
+      - name: Download container images
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13
+      - name: Check if detection needed
+        id: detection_guard
+        if: always()
+        env:
+          OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
+          HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+        run: |
+          if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+            echo "run_detection=true" >> "$GITHUB_OUTPUT"
+            echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+          else
+            echo "run_detection=false" >> "$GITHUB_OUTPUT"
+            echo "Detection skipped: no agent outputs or patches to analyze"
+          fi
+      - name: Clear MCP configuration for detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
+          rm -f /home/runner/.copilot/mcp-config.json
+          rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+      - name: Prepare threat detection files
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
+          cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
+          cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
+          for f in /tmp/gh-aw/aw-*.patch; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          for f in /tmp/gh-aw/aw-*.bundle; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          echo "Prepared threat detection files:"
+          ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+      - name: Setup threat detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+          WORKFLOW_DESCRIPTION: "Keeps agentic workflows up to date by running `gh aw upgrade` and `gh aw compile` daily.\nIf changes are detected, pushes them to a long-lived branch and creates or updates a PR."
+          HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
+            await main();
+      - name: Ensure threat-detection directory and log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection
+          touch /tmp/gh-aw/threat-detection/detection.log
+      - name: Install GitHub Copilot CLI
+        run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
+        env:
+          GH_HOST: github.com
+      - name: Install AWF binary
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13
+      - name: Execute GitHub Copilot CLI
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        id: detection_agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        timeout-minutes: 20
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
+          GH_AW_PHASE: detection
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_VERSION: v0.67.1
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Upload threat detection log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: detection
+          path: /tmp/gh-aw/threat-detection/detection.log
+          if-no-files-found: ignore
+      - name: Parse and conclude threat detection
+        id: detection_conclusion
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+            await main();
+
+  safe_outputs:
+    needs:
+      - activation
+      - agent
+      - detection
+    if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+      issues: write
+      pull-requests: write
+    timeout-minutes: 15
+    env:
+      GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/aw-auto-update"
+      GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+      GH_AW_ENGINE_ID: "copilot"
+      GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+      GH_AW_WORKFLOW_ID: "aw-auto-update"
+      GH_AW_WORKFLOW_NAME: "Agentic Workflow Auto-Update"
+    outputs:
+      code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
+      code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
+      create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
+      create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
+      created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
+      created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }}
+      process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
+      process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+      push_commit_sha: ${{ steps.process_safe_outputs.outputs.push_commit_sha }}
+      push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Download patch artifact
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Checkout repository
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') || (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
+          token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          persist-credentials: false
+          fetch-depth: 1
+      - name: Configure Git credentials
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') || (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Configure GH_HOST for enterprise compatibility
+        id: ghes-host-config
+        shell: bash
+        run: |
+          # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+          # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+          GH_HOST="${GITHUB_SERVER_URL#https://}"
+          GH_HOST="${GH_HOST#http://}"
+          echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+      - name: Process Safe Outputs
+        id: process_safe_outputs
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_API_URL: ${{ github.api_url }}
+          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":false,\"labels\":[\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[Auto Update] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"labels\":[\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\",\"title_prefix\":\"[Auto Update] \"},\"report_incomplete\":{}}"
+          GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
+            await main();
+      - name: Upload Safe Output Items
+        if: always()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: safe-output-items
+          path: /tmp/gh-aw/safe-output-items.jsonl
+          if-no-files-found: ignore
+
diff --git a/.github/workflows/aw-auto-update.md b/.github/workflows/aw-auto-update.md
new file mode 100644
index 00000000000..2fcf6524cd1
--- /dev/null
+++ b/.github/workflows/aw-auto-update.md
@@ -0,0 +1,61 @@
+---
+description: |
+  Keeps agentic workflows up to date by running `gh aw upgrade` and `gh aw compile` daily.
+  If changes are detected, pushes them to a long-lived branch and creates or updates a PR.
+
+on:
+  schedule: every 24h
+  workflow_dispatch:
+
+timeout-minutes: 15
+
+permissions: read-all
+
+network:
+  allowed:
+  - defaults
+
+checkout:
+  ref: main
+
+tools:
+  github:
+    toolsets: [pull_requests]
+    min-integrity: none
+  bash: true
+
+safe-outputs:
+  create-pull-request:
+    draft: false
+    title-prefix: "[Auto Update] "
+    labels: [automation]
+    max: 1
+  push-to-pull-request-branch:
+    target: "*"
+    title-prefix: "[Auto Update] "
+    labels: [automation]
+    max: 1
+---
+
+# Agentic Workflow Auto-Update
+
+You are a maintenance bot that keeps the repository's agentic workflow infrastructure current.
+
+## Task
+
+1. **Upgrade**: Run `gh aw upgrade` to update the gh-aw CLI version and apply any codemods.
+2. **Compile**: Run `gh aw compile` to recompile all workflows and verify 0 errors.
+3. **Check for changes**: Run `git diff` to see if anything changed.
+4. **If no changes**: Report "Already up to date" and exit.
+5. **If changes exist**:
+   - Check if an open PR titled `[Auto Update] Agentic workflows` already exists (search open PRs).
+   - If a PR exists, push the changes to its branch (`agentics/auto-update-gh-aw`) to update it. Leave a brief comment noting what changed (e.g. "Updated gh-aw-actions/setup from vX to vY").
+   - If no PR exists, create a new PR from branch `agentics/auto-update-gh-aw` to `main` with title `[Auto Update] Agentic workflows` and a body summarizing the changes.
+
+## Rules
+
+- Only commit changes to files managed by `gh aw`: `.github/workflows/`, `.github/aw/`, `.github/agents/`.
+- Use a single commit with message: `Update agentic workflows via gh aw upgrade`.
+- The branch name must always be `agentics/auto-update-gh-aw`.
+- If `gh aw compile` reports errors, do **not** create or update a PR. Instead, report the errors and exit.
+- Be concise in PR descriptions and comments.
diff --git a/.github/workflows/regression-pr-shepherd.lock.yml b/.github/workflows/regression-pr-shepherd.lock.yml
new file mode 100644
index 00000000000..052b4dc3e52
--- /dev/null
+++ b/.github/workflows/regression-pr-shepherd.lock.yml
@@ -0,0 +1,1315 @@
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"7cca6ca8f7bebfc8c484c6f21c2aa541e261e9b16d943a1969219de77fcaa4e6","compiler_version":"v0.67.1","strict":true,"agent_id":"copilot"}
+#    ___                   _   _      
+#   / _ \                 | | (_)     
+#  | |_| | __ _  ___ _ __ | |_ _  ___ 
+#  |  _  |/ _` |/ _ \ '_ \| __| |/ __|
+#  | | | | (_| |  __/ | | | |_| | (__ 
+#  \_| |_/\__, |\___|_| |_|\__|_|\___|
+#          __/ |
+#  _    _ |___/ 
+# | |  | |                / _| |
+# | |  | | ___ _ __ _  __| |_| | _____      ____
+# | |/\| |/ _ \ '__| |/ /|  _| |/ _ \ \ /\ / / ___|
+# \  /\  / (_) | | | | ( | | | | (_) \ V  V /\__ \
+#  \/  \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw (v0.67.1). DO NOT EDIT.
+#
+# To update this file, edit the corresponding .md file and run:
+#   gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# Shepherds open regression test PRs (AI-Issue-Regression-PR label) to completion.
+# Fixes CI failures, addresses review feedback, and detects when a "regression test"
+# actually proves the bug still exists.
+# Runs 6 times per day.
+#
+# Secrets used:
+#   - COPILOT_GITHUB_TOKEN
+#   - GH_AW_CI_TRIGGER_TOKEN
+#   - GH_AW_GITHUB_MCP_SERVER_TOKEN
+#   - GH_AW_GITHUB_TOKEN
+#   - GITHUB_TOKEN
+#
+# Custom actions used:
+#   - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+#   - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+#   - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+#   - actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+#   - github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+
+name: "Regression PR Shepherd"
+"on":
+  schedule:
+  - cron: "54 */4 * * *"
+    # Friendly format: every 4h (scattered)
+  workflow_dispatch:
+    inputs:
+      aw_context:
+        default: ""
+        description: Agent caller context (used internally by Agentic Workflows).
+        required: false
+        type: string
+
+permissions: {}
+
+concurrency:
+  group: "gh-aw-${{ github.workflow }}"
+
+run-name: "Regression PR Shepherd"
+
+jobs:
+  activation:
+    runs-on: ubuntu-slim
+    permissions:
+      contents: read
+    outputs:
+      comment_id: ""
+      comment_repo: ""
+      lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+      model: ${{ steps.generate_aw_info.outputs.model }}
+      secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+      - name: Generate agentic run info
+        id: generate_aw_info
+        env:
+          GH_AW_INFO_ENGINE_ID: "copilot"
+          GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
+          GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }}
+          GH_AW_INFO_VERSION: "latest"
+          GH_AW_INFO_AGENT_VERSION: "latest"
+          GH_AW_INFO_CLI_VERSION: "v0.67.1"
+          GH_AW_INFO_WORKFLOW_NAME: "Regression PR Shepherd"
+          GH_AW_INFO_EXPERIMENTAL: "false"
+          GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+          GH_AW_INFO_STAGED: "false"
+          GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","dotnet"]'
+          GH_AW_INFO_FIREWALL_ENABLED: "true"
+          GH_AW_INFO_AWF_VERSION: "v0.25.13"
+          GH_AW_INFO_AWMG_VERSION: ""
+          GH_AW_INFO_FIREWALL_TYPE: "squid"
+          GH_AW_COMPILED_STRICT: "true"
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
+            await main(core, context);
+      - name: Validate COPILOT_GITHUB_TOKEN secret
+        id: validate-secret
+        run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
+        env:
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+      - name: Checkout .github and .agents folders
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+          sparse-checkout: |
+            .github
+            .agents
+          sparse-checkout-cone-mode: true
+          fetch-depth: 1
+      - name: Check workflow lock file
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_WORKFLOW_FILE: "regression-pr-shepherd.lock.yml"
+          GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
+            await main();
+      - name: Check compile-agentic version
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_COMPILED_VERSION: "v0.67.1"
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
+            await main();
+      - name: Create prompt with built-in context
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
+          GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+          GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
+          GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
+          GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+          GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+          GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+          GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+          GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+          GH_AW_WIKI_NOTE: ${{ '' }}
+        # poutine:ignore untrusted_checkout_exec
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
+          {
+          cat << 'GH_AW_PROMPT_0435ed96397de12a_EOF'
+          <system>
+          GH_AW_PROMPT_0435ed96397de12a_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
+          cat << 'GH_AW_PROMPT_0435ed96397de12a_EOF'
+          <safe-output-tools>
+          Tools: add_comment(max:5), remove_labels(max:5), push_to_pull_request_branch(max:10), missing_tool, missing_data, noop
+          GH_AW_PROMPT_0435ed96397de12a_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
+          cat << 'GH_AW_PROMPT_0435ed96397de12a_EOF'
+          </safe-output-tools>
+          <github-context>
+          The following GitHub context information is available for this workflow:
+          {{#if __GH_AW_GITHUB_ACTOR__ }}
+          - **actor**: __GH_AW_GITHUB_ACTOR__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_REPOSITORY__ }}
+          - **repository**: __GH_AW_GITHUB_REPOSITORY__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_WORKSPACE__ }}
+          - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
+          - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
+          - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
+          - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
+          - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
+          {{/if}}
+          {{#if __GH_AW_GITHUB_RUN_ID__ }}
+          - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+          {{/if}}
+          </github-context>
+          
+          GH_AW_PROMPT_0435ed96397de12a_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+          cat << 'GH_AW_PROMPT_0435ed96397de12a_EOF'
+          </system>
+          {{#runtime-import .github/workflows/regression-pr-shepherd.md}}
+          GH_AW_PROMPT_0435ed96397de12a_EOF
+          } > "$GH_AW_PROMPT"
+      - name: Interpolate variables and render templates
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
+            await main();
+      - name: Substitute placeholders
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+          GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
+          GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
+          GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+          GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+          GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+          GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+          GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+          GH_AW_MEMORY_BRANCH_NAME: 'memory/regression-pr-shepherd'
+          GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 10240 bytes (0.01 MB) per file\n- **Max File Count**: 100 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 100 KB)\n"
+          GH_AW_MEMORY_DESCRIPTION: ''
+          GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/'
+          GH_AW_MEMORY_TARGET_REPO: ' of the current repository'
+          GH_AW_WIKI_NOTE: ''
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            
+            const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
+            
+            // Call the substitution function
+            return await substitutePlaceholders({
+              file: process.env.GH_AW_PROMPT,
+              substitutions: {
+                GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+                GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
+                GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
+                GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
+                GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
+                GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
+                GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
+                GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
+                GH_AW_MEMORY_BRANCH_NAME: process.env.GH_AW_MEMORY_BRANCH_NAME,
+                GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS,
+                GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION,
+                GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR,
+                GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO,
+                GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE
+              }
+            });
+      - name: Validate prompt placeholders
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        # poutine:ignore untrusted_checkout_exec
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
+      - name: Print prompt
+        env:
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        # poutine:ignore untrusted_checkout_exec
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
+      - name: Upload activation artifact
+        if: success()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: activation
+          path: |
+            /tmp/gh-aw/aw_info.json
+            /tmp/gh-aw/aw-prompts/prompt.txt
+            /tmp/gh-aw/github_rate_limits.jsonl
+          if-no-files-found: ignore
+          retention-days: 1
+
+  agent:
+    needs: activation
+    runs-on: ubuntu-latest
+    permissions: read-all
+    concurrency:
+      group: "gh-aw-copilot-${{ github.workflow }}"
+    env:
+      DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
+      GH_AW_ASSETS_ALLOWED_EXTS: ""
+      GH_AW_ASSETS_BRANCH: ""
+      GH_AW_ASSETS_MAX_SIZE_KB: 0
+      GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+      GH_AW_WORKFLOW_ID_SANITIZED: regressionprshepherd
+    outputs:
+      checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
+      effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
+      has_patch: ${{ steps.collect_output.outputs.has_patch }}
+      inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
+      model: ${{ needs.activation.outputs.model }}
+      output: ${{ steps.collect_output.outputs.output }}
+      output_types: ${{ steps.collect_output.outputs.output_types }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Set runtime paths
+        id: set-runtime-paths
+        run: |
+          echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_OUTPUT"
+          echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_OUTPUT"
+          echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_OUTPUT"
+      - name: Checkout repository
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+      - name: Create gh-aw temp directory
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
+      - name: Configure gh CLI for GitHub Enterprise
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
+        env:
+          GH_TOKEN: ${{ github.token }}
+      # Repo memory git-based storage configuration from frontmatter processed below
+      - name: Clone repo-memory branch (default)
+        env:
+          GH_TOKEN: ${{ github.token }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          BRANCH_NAME: memory/regression-pr-shepherd
+          TARGET_REPO: ${{ github.repository }}
+          MEMORY_DIR: /tmp/gh-aw/repo-memory/default
+          CREATE_ORPHAN: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/clone_repo_memory_branch.sh
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Checkout PR branch
+        id: checkout-pr
+        if: |
+          github.event.pull_request || github.event.issue.pull_request
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
+            await main();
+      - name: Install GitHub Copilot CLI
+        run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
+        env:
+          GH_HOST: github.com
+      - name: Install AWF binary
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13
+      - name: Parse integrity filter lists
+        id: parse-guard-vars
+        env:
+          GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+          GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+          GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh
+      - name: Download container images
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.14 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
+      - name: Write Safe Outputs Config
+        run: |
+          mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
+          mkdir -p /tmp/gh-aw/safeoutputs
+          mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_4331bdca935c82a1_EOF'
+          {"add_comment":{"hide_older_comments":true,"max":5,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":10240,"max_patch_size":10240}]},"push_to_pull_request_branch":{"allowed_files":["tests/**","vsintegration/tests/**"],"if_no_changes":"warn","labels":["AI-Issue-Regression-PR"],"max":10,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_files_policy":"fallback-to-issue","protected_path_prefixes":[".github/",".agents/"],"target":"*","title_prefix":"Add regression test: "},"remove_labels":{"allowed":["AI-thinks-issue-fixed"],"max":5,"target":"*"},"report_incomplete":{}}
+          GH_AW_SAFE_OUTPUTS_CONFIG_4331bdca935c82a1_EOF
+      - name: Write Safe Outputs Tools
+        run: |
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_f7ff2fc9cf0f40f8_EOF'
+          {
+            "description_suffixes": {
+              "add_comment": " CONSTRAINTS: Maximum 5 comment(s) can be added. Target: *.",
+              "push_to_pull_request_branch": " CONSTRAINTS: Maximum 10 push(es) can be made. The target pull request title must start with \"Add regression test: \".",
+              "remove_labels": " CONSTRAINTS: Maximum 5 label(s) can be removed. Only these labels can be removed: [AI-thinks-issue-fixed]. Target: *."
+            },
+            "repo_params": {},
+            "dynamic_tools": []
+          }
+          GH_AW_SAFE_OUTPUTS_TOOLS_META_f7ff2fc9cf0f40f8_EOF
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_d0c199d7e157b9c2_EOF'
+          {
+            "add_comment": {
+              "defaultMax": 1,
+              "fields": {
+                "body": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "item_number": {
+                  "issueOrPRNumber": true
+                },
+                "repo": {
+                  "type": "string",
+                  "maxLength": 256
+                }
+              }
+            },
+            "missing_data": {
+              "defaultMax": 20,
+              "fields": {
+                "alternatives": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "context": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "data_type": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                },
+                "reason": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                }
+              }
+            },
+            "missing_tool": {
+              "defaultMax": 20,
+              "fields": {
+                "alternatives": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 512
+                },
+                "reason": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "tool": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                }
+              }
+            },
+            "noop": {
+              "defaultMax": 1,
+              "fields": {
+                "message": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                }
+              }
+            },
+            "push_to_pull_request_branch": {
+              "defaultMax": 1,
+              "fields": {
+                "branch": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "message": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "pull_request_number": {
+                  "issueOrPRNumber": true
+                }
+              }
+            },
+            "remove_labels": {
+              "defaultMax": 5,
+              "fields": {
+                "item_number": {
+                  "issueNumberOrTemporaryId": true
+                },
+                "labels": {
+                  "required": true,
+                  "type": "array",
+                  "itemType": "string",
+                  "itemSanitize": true,
+                  "itemMaxLength": 128
+                },
+                "repo": {
+                  "type": "string",
+                  "maxLength": 256
+                }
+              }
+            },
+            "report_incomplete": {
+              "defaultMax": 5,
+              "fields": {
+                "details": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "reason": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 1024
+                }
+              }
+            }
+          }
+          GH_AW_SAFE_OUTPUTS_VALIDATION_d0c199d7e157b9c2_EOF
+          node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
+      - name: Generate Safe Outputs MCP Server Config
+        id: safe-outputs-config
+        run: |
+          # Generate a secure random API key (360 bits of entropy, 40+ chars)
+          # Mask immediately to prevent timing vulnerabilities
+          API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+          echo "::add-mask::${API_KEY}"
+          
+          PORT=3001
+          
+          # Set outputs for next steps
+          {
+            echo "safe_outputs_api_key=${API_KEY}"
+            echo "safe_outputs_port=${PORT}"
+          } >> "$GITHUB_OUTPUT"
+          
+          echo "Safe Outputs MCP server will run on port ${PORT}"
+          
+      - name: Start Safe Outputs MCP HTTP Server
+        id: safe-outputs-start
+        env:
+          DEBUG: '*'
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
+          GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
+          GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
+          GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
+          GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+        run: |
+          # Environment variables are set above to prevent template injection
+          export DEBUG
+          export GH_AW_SAFE_OUTPUTS
+          export GH_AW_SAFE_OUTPUTS_PORT
+          export GH_AW_SAFE_OUTPUTS_API_KEY
+          export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
+          export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
+          export GH_AW_MCP_LOG_DIR
+          
+          bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh
+          
+      - name: Start MCP Gateway
+        id: start-mcp-gateway
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
+          GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+          GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          set -eo pipefail
+          mkdir -p /tmp/gh-aw/mcp-config
+          
+          # Export gateway environment variables for MCP config and gateway script
+          export MCP_GATEWAY_PORT="80"
+          export MCP_GATEWAY_DOMAIN="host.docker.internal"
+          MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+          echo "::add-mask::${MCP_GATEWAY_API_KEY}"
+          export MCP_GATEWAY_API_KEY
+          export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
+          mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
+          export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
+          export DEBUG="*"
+          
+          export GH_AW_ENGINE="copilot"
+          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.14'
+          
+          mkdir -p /home/runner/.copilot
+          cat << GH_AW_MCP_CONFIG_ba7195fc3a0ae0bd_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
+          {
+            "mcpServers": {
+              "github": {
+                "type": "stdio",
+                "container": "ghcr.io/github/github-mcp-server:v0.32.0",
+                "env": {
+                  "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
+                  "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
+                  "GITHUB_READ_ONLY": "1",
+                  "GITHUB_TOOLSETS": "all"
+                },
+                "guard-policies": {
+                  "allow-only": {
+                    "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+                    "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+                    "min-integrity": "none",
+                    "repos": "all",
+                    "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
+                  }
+                }
+              },
+              "safeoutputs": {
+                "type": "http",
+                "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
+                "headers": {
+                  "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+                },
+                "guard-policies": {
+                  "write-sink": {
+                    "accept": [
+                      "*"
+                    ]
+                  }
+                }
+              }
+            },
+            "gateway": {
+              "port": $MCP_GATEWAY_PORT,
+              "domain": "${MCP_GATEWAY_DOMAIN}",
+              "apiKey": "${MCP_GATEWAY_API_KEY}",
+              "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
+            }
+          }
+          GH_AW_MCP_CONFIG_ba7195fc3a0ae0bd_EOF
+      - name: Download activation artifact
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: activation
+          path: /tmp/gh-aw
+      - name: Clean git credentials
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh
+      - name: Execute GitHub Copilot CLI
+        id: agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        timeout-minutes: 30
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.vsblob.vsassets.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,builds.dotnet.microsoft.com,ci.dot.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkgs.dev.azure.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
+          GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
+          GH_AW_PHASE: agent
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_VERSION: v0.67.1
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Detect inference access error
+        id: detect-inference-error
+        if: always()
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Copy Copilot session state files to logs
+        if: always()
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh
+      - name: Stop MCP Gateway
+        if: always()
+        continue-on-error: true
+        env:
+          MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+          MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+          GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID"
+      - name: Redact secrets in logs
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
+            await main();
+        env:
+          GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+          SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+          SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+          SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      - name: Append agent step summary
+        if: always()
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
+      - name: Copy Safe Outputs
+        if: always()
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+        run: |
+          mkdir -p /tmp/gh-aw
+          cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
+      - name: Ingest agent output
+        id: collect_output
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_ALLOWED_DOMAINS: "*.vsblob.vsassets.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,builds.dotnet.microsoft.com,ci.dot.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkgs.dev.azure.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com"
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_API_URL: ${{ github.api_url }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
+            await main();
+      - name: Parse agent logs for step summary
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
+            await main();
+      - name: Parse MCP Gateway logs for step summary
+        if: always()
+        id: parse-mcp-gateway
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
+            await main();
+      - name: Print firewall logs
+        if: always()
+        continue-on-error: true
+        env:
+          AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
+        run: |
+          # Fix permissions on firewall logs so they can be uploaded as artifacts
+          # AWF runs with sudo, creating files owned by root
+          sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
+          # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
+          if command -v awf &> /dev/null; then
+            awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
+          else
+            echo 'AWF binary not installed, skipping firewall log summary'
+          fi
+      - name: Parse token usage for step summary
+        if: always()
+        continue-on-error: true
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
+            await main();
+      - name: Write agent output placeholder if missing
+        if: always()
+        run: |
+          if [ ! -f /tmp/gh-aw/agent_output.json ]; then
+            echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
+          fi
+      # Upload repo memory as artifacts for push job
+      - name: Upload repo-memory artifact (default)
+        if: always()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: repo-memory-default
+          path: /tmp/gh-aw/repo-memory/default
+          retention-days: 1
+          if-no-files-found: ignore
+      - name: Upload agent artifacts
+        if: always()
+        continue-on-error: true
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: agent
+          path: |
+            /tmp/gh-aw/aw-prompts/prompt.txt
+            /tmp/gh-aw/sandbox/agent/logs/
+            /tmp/gh-aw/redacted-urls.log
+            /tmp/gh-aw/mcp-logs/
+            /tmp/gh-aw/proxy-logs/
+            !/tmp/gh-aw/proxy-logs/proxy-tls/
+            /tmp/gh-aw/agent_usage.json
+            /tmp/gh-aw/agent-stdio.log
+            /tmp/gh-aw/agent/
+            /tmp/gh-aw/github_rate_limits.jsonl
+            /tmp/gh-aw/safeoutputs.jsonl
+            /tmp/gh-aw/agent_output.json
+            /tmp/gh-aw/aw-*.patch
+            /tmp/gh-aw/aw-*.bundle
+          if-no-files-found: ignore
+      - name: Upload firewall audit logs
+        if: always()
+        continue-on-error: true
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: firewall-audit-logs
+          path: |
+            /tmp/gh-aw/sandbox/firewall/logs/
+            /tmp/gh-aw/sandbox/firewall/audit/
+          if-no-files-found: ignore
+
+  conclusion:
+    needs:
+      - activation
+      - agent
+      - detection
+      - push_repo_memory
+      - safe_outputs
+    if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+      discussions: write
+      issues: write
+      pull-requests: write
+    concurrency:
+      group: "gh-aw-conclusion-regression-pr-shepherd"
+      cancel-in-progress: false
+    outputs:
+      incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
+      noop_message: ${{ steps.noop.outputs.noop_message }}
+      tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
+      total_count: ${{ steps.missing_tool.outputs.total_count }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Process No-Op Messages
+        id: noop
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_NOOP_MAX: "1"
+          GH_AW_WORKFLOW_NAME: "Regression PR Shepherd"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_NOOP_REPORT_AS_ISSUE: "true"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
+            await main();
+      - name: Record Missing Tool
+        id: missing_tool
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
+          GH_AW_WORKFLOW_NAME: "Regression PR Shepherd"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
+            await main();
+      - name: Record Incomplete
+        id: report_incomplete
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
+          GH_AW_WORKFLOW_NAME: "Regression PR Shepherd"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
+            await main();
+      - name: Handle Agent Failure
+        id: handle_agent_failure
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_WORKFLOW_NAME: "Regression PR Shepherd"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_WORKFLOW_ID: "regression-pr-shepherd"
+          GH_AW_ENGINE_ID: "copilot"
+          GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
+          GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+          GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+          GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
+          GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
+          GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+          GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }}
+          GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }}
+          GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }}
+          GH_AW_REPO_MEMORY_PATCH_SIZE_EXCEEDED_default: ${{ needs.push_repo_memory.outputs.patch_size_exceeded_default }}
+          GH_AW_GROUP_REPORTS: "false"
+          GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+          GH_AW_TIMEOUT_MINUTES: "30"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
+            await main();
+
+  detection:
+    needs:
+      - activation
+      - agent
+    if: >
+      always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+    outputs:
+      detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+      detection_success: ${{ steps.detection_conclusion.outputs.success }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Checkout repository for patch context
+        if: needs.agent.outputs.has_patch == 'true'
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+      # --- Threat Detection ---
+      - name: Download container images
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13
+      - name: Check if detection needed
+        id: detection_guard
+        if: always()
+        env:
+          OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
+          HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+        run: |
+          if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+            echo "run_detection=true" >> "$GITHUB_OUTPUT"
+            echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+          else
+            echo "run_detection=false" >> "$GITHUB_OUTPUT"
+            echo "Detection skipped: no agent outputs or patches to analyze"
+          fi
+      - name: Clear MCP configuration for detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
+          rm -f /home/runner/.copilot/mcp-config.json
+          rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+      - name: Prepare threat detection files
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
+          cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
+          cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
+          for f in /tmp/gh-aw/aw-*.patch; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          for f in /tmp/gh-aw/aw-*.bundle; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          echo "Prepared threat detection files:"
+          ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+      - name: Setup threat detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          WORKFLOW_NAME: "Regression PR Shepherd"
+          WORKFLOW_DESCRIPTION: "Shepherds open regression test PRs (AI-Issue-Regression-PR label) to completion.\nFixes CI failures, addresses review feedback, and detects when a \"regression test\"\nactually proves the bug still exists.\nRuns 6 times per day."
+          HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
+            await main();
+      - name: Ensure threat-detection directory and log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection
+          touch /tmp/gh-aw/threat-detection/detection.log
+      - name: Install GitHub Copilot CLI
+        run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
+        env:
+          GH_HOST: github.com
+      - name: Install AWF binary
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13
+      - name: Execute GitHub Copilot CLI
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        id: detection_agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        timeout-minutes: 20
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
+          GH_AW_PHASE: detection
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_VERSION: v0.67.1
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Upload threat detection log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: detection
+          path: /tmp/gh-aw/threat-detection/detection.log
+          if-no-files-found: ignore
+      - name: Parse and conclude threat detection
+        id: detection_conclusion
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+            await main();
+
+  push_repo_memory:
+    needs:
+      - activation
+      - agent
+      - detection
+    if: >
+      always() && (needs.detection.result == 'success' || needs.detection.result == 'skipped') &&
+      needs.agent.result == 'success'
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+    concurrency:
+      group: "push-repo-memory-${{ github.repository }}|memory/regression-pr-shepherd"
+      cancel-in-progress: false
+    outputs:
+      patch_size_exceeded_default: ${{ steps.push_repo_memory_default.outputs.patch_size_exceeded }}
+      validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }}
+      validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Checkout repository
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+          sparse-checkout: .
+      - name: Configure Git credentials
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Download repo-memory artifact (default)
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        continue-on-error: true
+        with:
+          name: repo-memory-default
+          path: /tmp/gh-aw/repo-memory/default
+      - name: Push repo-memory changes (default)
+        id: push_repo_memory_default
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_TOKEN: ${{ github.token }}
+          GITHUB_RUN_ID: ${{ github.run_id }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          ARTIFACT_DIR: /tmp/gh-aw/repo-memory/default
+          MEMORY_ID: default
+          TARGET_REPO: ${{ github.repository }}
+          BRANCH_NAME: memory/regression-pr-shepherd
+          MAX_FILE_SIZE: 10240
+          MAX_FILE_COUNT: 100
+          MAX_PATCH_SIZE: 10240
+          ALLOWED_EXTENSIONS: '[]'
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/push_repo_memory.cjs');
+            await main();
+
+  safe_outputs:
+    needs:
+      - activation
+      - agent
+      - detection
+    if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
+    runs-on: ubuntu-slim
+    permissions:
+      contents: write
+      discussions: write
+      issues: write
+      pull-requests: write
+    timeout-minutes: 15
+    env:
+      GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/regression-pr-shepherd"
+      GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+      GH_AW_ENGINE_ID: "copilot"
+      GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+      GH_AW_WORKFLOW_ID: "regression-pr-shepherd"
+      GH_AW_WORKFLOW_NAME: "Regression PR Shepherd"
+    outputs:
+      code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
+      code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
+      comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
+      comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
+      create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
+      create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
+      process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
+      process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+      push_commit_sha: ${{ steps.process_safe_outputs.outputs.push_commit_sha }}
+      push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Download patch artifact
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Checkout repository
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
+          token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          persist-credentials: false
+          fetch-depth: 1
+      - name: Configure Git credentials
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
+      - name: Configure GH_HOST for enterprise compatibility
+        id: ghes-host-config
+        shell: bash
+        run: |
+          # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+          # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+          GH_HOST="${GITHUB_SERVER_URL#https://}"
+          GH_HOST="${GH_HOST#http://}"
+          echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+      - name: Process Safe Outputs
+        id: process_safe_outputs
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_ALLOWED_DOMAINS: "*.vsblob.vsassets.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,builds.dotnet.microsoft.com,ci.dot.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkgs.dev.azure.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com"
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_API_URL: ${{ github.api_url }}
+          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":5,\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\"tests/**\",\"vsintegration/tests/**\"],\"if_no_changes\":\"warn\",\"labels\":[\"AI-Issue-Regression-PR\"],\"max\":10,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_files_policy\":\"fallback-to-issue\",\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\",\"title_prefix\":\"Add regression test: \"},\"remove_labels\":{\"allowed\":[\"AI-thinks-issue-fixed\"],\"max\":5,\"target\":\"*\"},\"report_incomplete\":{}}"
+          GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
+            await main();
+      - name: Upload Safe Output Items
+        if: always()
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: safe-output-items
+          path: /tmp/gh-aw/safe-output-items.jsonl
+          if-no-files-found: ignore
+
diff --git a/.github/workflows/regression-pr-shepherd.md b/.github/workflows/regression-pr-shepherd.md
new file mode 100644
index 00000000000..72a3bb76f64
--- /dev/null
+++ b/.github/workflows/regression-pr-shepherd.md
@@ -0,0 +1,165 @@
+---
+description: |
+  Shepherds open regression test PRs (AI-Issue-Regression-PR label) to completion.
+  Fixes CI failures, addresses review feedback, and detects when a "regression test"
+  actually proves the bug still exists.
+  Runs 6 times per day.
+
+on:
+  schedule: every 4h
+  workflow_dispatch:
+
+timeout-minutes: 30
+
+permissions: read-all
+
+network:
+  allowed:
+  - defaults
+  - dotnet
+
+safe-outputs:
+  add-comment:
+    max: 5
+    target: "*"
+    hide-older-comments: true
+  push-to-pull-request-branch:
+    target: "*"
+    title-prefix: "Add regression test: "
+    labels: [AI-Issue-Regression-PR]
+    max: 10
+    allowed-files:
+      - "tests/**"
+      - "vsintegration/tests/**"
+    protected-files: fallback-to-issue
+  remove-labels:
+    allowed: ["AI-thinks-issue-fixed"]
+    max: 5
+    target: "*"
+
+tools:
+  github:
+    toolsets: [all]
+    min-integrity: none
+  bash: true
+  repo-memory: true
+---
+
+# Regression PR Shepherd
+
+You shepherd open regression test PRs to completion. These PRs add tests for issues labeled `AI-thinks-issue-fixed`. They should be simple — only touching files under `tests/` or `vsintegration/tests/`.
+
+## Principles
+
+- **Fix forward**: CI failures and review feedback should be addressed, not ignored.
+- **Honesty over ego**: If the test proves the bug still exists, say so clearly.
+- **Zero context assumption**: When summoning maintainers, explain everything from scratch — they haven't read the PR or issue recently.
+- **One comment per PR per run**: Never post multiple comments on the same PR in a single run.
+
+## Process
+
+### Step 1 — Gather open PRs
+
+List all open PRs with the `AI-Issue-Regression-PR` label:
+```bash
+gh pr list --label "AI-Issue-Regression-PR" --state open --json number,title,headRefName,updatedAt,isDraft,headRepository
+```
+
+**Strict eligibility check — apply ALL of these filters before processing a PR:**
+1. The PR **must** have the `AI-Issue-Regression-PR` label (enforced by the `gh pr list` filter above).
+2. The PR title **must** start with `Add regression test:`. If it does not, skip it — it is not a regression test PR.
+3. The PR **must not** be a draft (`isDraft: false`). Draft PRs are work-in-progress and must not be touched.
+4. The PR **must** originate from `dotnet/fsharp` — the `headRepository` owner must be `dotnet` and name must be `fsharp`. Never touch PRs from external forks.
+
+**If a PR fails any of these checks, skip it silently — do not comment, do not attempt any changes.**
+
+**Process at most 3 PRs per run.** Prioritize PRs that have unaddressed review feedback (Category A) or CI failures (Category B) over healthy PRs (Category C). If more than 3 PRs need work, the next scheduled run will pick up the rest.
+
+For each PR, determine which category it falls into (check in this order):
+
+### Step 2 — Categorize each PR
+
+First, do a quick triage pass: check the mergeable state and latest check-run status for each PR before reading any diffs or logs. This avoids loading unnecessary context for Category C (healthy) PRs. Skip healthy PRs immediately.
+
+**Category A: Has unaddressed review feedback**
+
+Check for review comments posted since the last Repo Assist comment on this PR (look for the `🤖` marker). If new human review comments exist:
+
+1. Read the full PR diff, all review comments, the linked issue, and ALL issue comments
+2. Understand the reviewer's point in the full context of what the issue describes
+3. Make the requested change — push a fix commit to the PR branch
+4. Reply to each review thread confirming the change, quoting the relevant new code
+
+**Category B: CI failure or merge conflict**
+
+Check the PR's check runs and mergeable state. 
+
+**B0 — Merge conflict**: The PR branch is behind main and has conflicts. Since these PRs only touch test files, conflicts are typically `.fsproj` `<Compile Include>` ordering or test file edits on the same lines. Fix by:
+1. Check out the PR branch: `gh pr checkout {number}`
+2. Rebase onto main: `git fetch origin main && git rebase origin/main`
+3. Resolve conflicts — for `.fsproj` conflicts, keep both entries in alphabetical order. For test file conflicts, keep both tests.
+4. **Verify scope**: Run `git diff --name-only origin/main` and confirm only files under `tests/` or `vsintegration/tests/` are changed. If unrelated files appear (e.g., `.github/` files from main), reset them: `git checkout origin/main -- .github/`
+5. Build the test project to verify: `dotnet build tests/{TestProject}/{TestProject}.fsproj -c Release`
+6. Push the rebased branch to update the PR
+
+If any checks failed:
+
+1. Fetch the failed job logs
+2. Analyze the failure
+
+   **B1 — Infrastructure/flaky failure** (unrelated to the test): Retry by pushing an empty commit or re-running the workflow.
+
+   **B2 — Test compilation or setup error** (e.g., missing `<Compile Include>`, wrong namespace, syntax error): Fix the test code, push the fix.
+
+   **B3 — The added test itself fails, reproducing the original bug**: This means the issue is **NOT fixed**. The `AI-thinks-issue-fixed` label was wrong. Do ALL of the following:
+   - Remove the `AI-thinks-issue-fixed` label from the linked issue
+   - Comment on the linked issue — **brief and apologetic**, this comment will live on the issue permanently:
+     ```
+     🤖 Issue still reproduces. Regression test in #NNNN (PR) confirms it. Still errors with: `{one-line error summary}`. Apologies for the incorrect label.
+     ```
+   - Comment on the PR tagging `@T-Gro` and `@abonie` — **this is where the full context goes**. Assume they have zero context:
+     ```
+     🤖 *This is an automated response from Regression PR Shepherd.*
+
+     This regression test proves the bug in #{issue} still exists. Closing this PR.
+
+     **The bug**: {one-paragraph description from issue body + comments}
+
+     **The test**: {what the test does, link to the test code}
+
+     **The failure**:
+     ```
+     {exact error output}
+     ```
+
+     The `AI-thinks-issue-fixed` label has been removed from #{issue}.
+     cc @T-Gro @abonie
+     ```
+   - Close the PR
+
+   **B4 — Other test failures** (not the added test): Check if these are known flaky tests. If unrelated to the PR's changes, note this in a comment and re-trigger CI.
+
+**Category C: No feedback, CI passing or still running**
+
+Do nothing. The PR is healthy.
+
+### Step 3 — Avoid duplicate work
+
+Before pushing any fix:
+- Check if you already pushed a fix for the same review comment or CI failure (compare your last commit message against the feedback)
+- If the last commit on the PR is from Repo Assist and no new human feedback or CI results appeared since, skip this PR
+
+### Step 4 — Update memory
+
+Track which PRs you've processed and the last review comment timestamp you addressed, so the next run only processes new feedback.
+
+## Guidelines
+
+- **Never modify files outside `tests/` or `vsintegration/tests/`** — if a fix requires changing `src/`, that's beyond scope. Comment explaining this and tag maintainers.
+- **Never modify `.github/` files** — workflow definitions, agent configs, skills, and lock files are managed by the dedicated `aw-auto-update` workflow. Do not touch `.github/workflows/`, `.github/agents/`, `.github/aw/`, or `.github/skills/`.
+- **Never touch draft PRs or PRs from external forks** — these are out of scope even if they have the right label. Skip them silently.
+- **Verify before pushing**: After making changes or rebasing, run `git diff --name-only` and confirm every changed file is under `tests/` or `vsintegration/tests/`. If unrelated files appear in the diff (e.g., from a rebase picking up main's changes), use `git checkout origin/main -- <file>` to restore them before committing.
+- **Only comment on PRs with the `AI-Issue-Regression-PR` label or their linked issues** — never comment on any other issue or PR in the repository. If you need to tag maintainers about a bug that still exists, comment on the linked issue only.
+- Begin every comment with: `🤖 *This is an automated response from Regression PR Shepherd.*`
+- When fixing review feedback, keep changes minimal — address exactly what was requested.
+- When a test failure reveals a real bug (Category B3), be thorough and precise in the explanation. This is the most important thing you do.
diff --git a/.github/workflows/repo-assist.lock.yml b/.github/workflows/repo-assist.lock.yml
index ce4ed776b58..63ac932b60a 100644
--- a/.github/workflows/repo-assist.lock.yml
+++ b/.github/workflows/repo-assist.lock.yml
@@ -1,3 +1,4 @@
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5b1417f9659c3c23218a833a01c952daadb712d177723ca50714417548d469ff","compiler_version":"v0.67.1","strict":true,"agent_id":"copilot"}
 #    ___                   _   _      
 #   / _ \                 | | (_)     
 #  | |_| | __ _  ___ _ __ | |_ _  ___ 
@@ -12,15 +13,15 @@
 # \  /\  / (_) | | | | ( | | | | (_) \ V  V /\__ \
 #  \/  \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
 #
-# This file was automatically generated by gh-aw (v0.62.0). DO NOT EDIT.
+# This file was automatically generated by gh-aw (v0.67.1). DO NOT EDIT.
 #
-# To update this file, edit githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02 and run:
+# To update this file, edit githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404 and run:
 #   gh aw compile
 # Not all edits will cause changes to this file.
 #
 # For more information: https://github.github.com/gh-aw/introduction/overview/
 #
-# A friendly repository assistant that runs 4 times a day to support contributors and maintainers.
+# A friendly repository assistant that runs 2 times a day to support contributors and maintainers.
 # Can also be triggered on-demand via '/repo-assist <instructions>' to perform specific tasks.
 # - Labels and triages open issues
 # - Comments helpfully on open issues to unblock contributors and onboard newcomers
@@ -33,9 +34,21 @@
 # - Maintains a persistent memory of work done and what remains
 # Always polite, constructive, and mindful of the project's goals.
 #
-# Source: githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02
+# Source: githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404
 #
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"d75bcc7a75f547113f447da58a55e31496f5d71e97c382008b2356d2a3893cc0","compiler_version":"v0.62.0","strict":true}
+# Secrets used:
+#   - COPILOT_GITHUB_TOKEN
+#   - GH_AW_CI_TRIGGER_TOKEN
+#   - GH_AW_GITHUB_MCP_SERVER_TOKEN
+#   - GH_AW_GITHUB_TOKEN
+#   - GITHUB_TOKEN
+#
+# Custom actions used:
+#   - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+#   - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+#   - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+#   - actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+#   - github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
 
 name: "Repo Assist"
 "on":
@@ -66,8 +79,14 @@ name: "Repo Assist"
     - created
     - edited
   schedule:
-  - cron: "25 */6 * * *"
-  workflow_dispatch: null
+  - cron: "30 */12 * * *"
+  workflow_dispatch:
+    inputs:
+      aw_context:
+        default: ""
+        description: Agent caller context (used internally by Agentic Workflows).
+        required: false
+        type: string
 
 permissions: {}
 
@@ -79,21 +98,7 @@ run-name: "Repo Assist"
 jobs:
   activation:
     needs: pre_activation
-    if: >
-      (needs.pre_activation.outputs.activated == 'true') && (((github.event_name == 'issues' || github.event_name == 'issue_comment' ||
-      github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' ||
-      github.event_name == 'discussion_comment') && ((github.event_name == 'issues') && ((startsWith(github.event.issue.body, '/repo-assist ')) ||
-      (github.event.issue.body == '/repo-assist')) || (github.event_name == 'issue_comment') && (((startsWith(github.event.comment.body, '/repo-assist ')) ||
-      (github.event.comment.body == '/repo-assist')) && (github.event.issue.pull_request == null)) || (github.event_name == 'issue_comment') &&
-      (((startsWith(github.event.comment.body, '/repo-assist ')) || (github.event.comment.body == '/repo-assist')) &&
-      (github.event.issue.pull_request != null)) || (github.event_name == 'pull_request_review_comment') &&
-      ((startsWith(github.event.comment.body, '/repo-assist ')) || (github.event.comment.body == '/repo-assist')) ||
-      (github.event_name == 'pull_request') && ((startsWith(github.event.pull_request.body, '/repo-assist ')) ||
-      (github.event.pull_request.body == '/repo-assist')) || (github.event_name == 'discussion') && ((startsWith(github.event.discussion.body, '/repo-assist ')) ||
-      (github.event.discussion.body == '/repo-assist')) || (github.event_name == 'discussion_comment') && ((startsWith(github.event.comment.body, '/repo-assist ')) ||
-      (github.event.comment.body == '/repo-assist')))) || (!(github.event_name == 'issues' || github.event_name == 'issue_comment' ||
-      github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' ||
-      github.event_name == 'discussion_comment')))
+    if: "needs.pre_activation.outputs.activated == 'true' && ((github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment') && (github.event_name == 'issues' && (startsWith(github.event.issue.body, '/repo-assist ') || startsWith(github.event.issue.body, '/repo-assist\n') || github.event.issue.body == '/repo-assist') || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request == null || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request != null || github.event_name == 'pull_request_review_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') || github.event_name == 'pull_request' && (startsWith(github.event.pull_request.body, '/repo-assist ') || startsWith(github.event.pull_request.body, '/repo-assist\n') || github.event.pull_request.body == '/repo-assist') || github.event_name == 'discussion' && (startsWith(github.event.discussion.body, '/repo-assist ') || startsWith(github.event.discussion.body, '/repo-assist\n') || github.event.discussion.body == '/repo-assist') || github.event_name == 'discussion_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist')) || (!(github.event_name == 'issues')) && (!(github.event_name == 'issue_comment')) && (!(github.event_name == 'pull_request')) && (!(github.event_name == 'pull_request_review_comment')) && (!(github.event_name == 'discussion')) && (!(github.event_name == 'discussion_comment')))"
     runs-on: ubuntu-slim
     permissions:
       contents: read
@@ -108,30 +113,34 @@ jobs:
       lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
       model: ${{ steps.generate_aw_info.outputs.model }}
       secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.sanitized.outputs.text }}
       title: ${{ steps.sanitized.outputs.title }}
     steps:
       - name: Setup Scripts
-        uses: github/gh-aw-actions/setup@b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6 # v0.62.0
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
         with:
           destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
       - name: Generate agentic run info
         id: generate_aw_info
         env:
           GH_AW_INFO_ENGINE_ID: "copilot"
           GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
-          GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
-          GH_AW_INFO_VERSION: ""
+          GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }}
+          GH_AW_INFO_VERSION: "latest"
           GH_AW_INFO_AGENT_VERSION: "latest"
-          GH_AW_INFO_CLI_VERSION: "v0.62.0"
+          GH_AW_INFO_CLI_VERSION: "v0.67.1"
           GH_AW_INFO_WORKFLOW_NAME: "Repo Assist"
           GH_AW_INFO_EXPERIMENTAL: "false"
           GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
           GH_AW_INFO_STAGED: "false"
           GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","dotnet","python"]'
           GH_AW_INFO_FIREWALL_ENABLED: "true"
-          GH_AW_INFO_AWF_VERSION: "v0.24.3"
+          GH_AW_INFO_AWF_VERSION: "v0.25.13"
           GH_AW_INFO_AWMG_VERSION: ""
           GH_AW_INFO_FIREWALL_TYPE: "squid"
           GH_AW_COMPILED_STRICT: "true"
@@ -142,6 +151,19 @@ jobs:
             setupGlobals(core, github, context, exec, io);
             const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
             await main(core, context);
+      - name: Add eyes reaction for immediate feedback
+        id: react
+        if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_REACTION: "eyes"
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs');
+            await main();
       - name: Validate COPILOT_GITHUB_TOKEN secret
         id: validate-secret
         run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
@@ -156,28 +178,26 @@ jobs:
             .agents
           sparse-checkout-cone-mode: true
           fetch-depth: 1
-      - name: Add eyes reaction for immediate feedback
-        id: react
-        if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.id == github.repository_id)
+      - name: Check workflow lock file
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_REACTION: "eyes"
+          GH_AW_WORKFLOW_FILE: "repo-assist.lock.yml"
+          GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
         with:
-          github-token: ${{ secrets.GITHUB_TOKEN }}
           script: |
             const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
             setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs');
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
             await main();
-      - name: Check workflow file timestamps
+      - name: Check compile-agentic version
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_WORKFLOW_FILE: "repo-assist.lock.yml"
+          GH_AW_COMPILED_VERSION: "v0.67.1"
         with:
           script: |
             const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
             setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
             await main();
       - name: Compute current body text
         id: sanitized
@@ -190,10 +210,11 @@ jobs:
             await main();
       - name: Add comment with workflow run link
         id: add-comment
-        if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.id == github.repository_id)
+        if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
           GH_AW_WORKFLOW_NAME: "Repo Assist"
+          GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e Generated by 🌈 {workflow_name}, see [workflow run]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md).\",\"runStarted\":\"{workflow_name} is processing {event_type}, see [workflow run]({run_url})...\",\"runSuccess\":\"✓ {workflow_name} completed successfully, see [workflow run]({run_url}).\",\"runFailure\":\"✗ {workflow_name} encountered {status}, see [workflow run]({run_url}).\"}"
         with:
           script: |
             const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -203,7 +224,7 @@ jobs:
       - name: Create prompt with built-in context
         env:
           GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
-          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
           GH_AW_GITHUB_ACTOR: ${{ github.actor }}
           GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
           GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
@@ -216,20 +237,25 @@ jobs:
           GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }}
           GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: ${{ steps.sanitized.outputs.text }}
           GH_AW_WIKI_NOTE: ${{ '' }}
+        # poutine:ignore untrusted_checkout_exec
         run: |
           bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
           {
-          cat << 'GH_AW_PROMPT_EOF'
+          cat << 'GH_AW_PROMPT_3c8a400b2f885ebf_EOF'
           <system>
-          GH_AW_PROMPT_EOF
+          GH_AW_PROMPT_3c8a400b2f885ebf_EOF
           cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
           cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
           cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
           cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md"
           cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
-          cat << 'GH_AW_PROMPT_EOF'
+          cat << 'GH_AW_PROMPT_3c8a400b2f885ebf_EOF'
           <safe-output-tools>
-          Tools: add_comment, create_issue, update_issue, add_labels, missing_tool, missing_data, noop
+          Tools: add_comment(max:10), create_issue(max:4), update_issue, create_pull_request(max:10), add_labels(max:30), remove_labels(max:10), push_to_pull_request_branch(max:4), missing_tool, missing_data, noop
+          GH_AW_PROMPT_3c8a400b2f885ebf_EOF
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
+          cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
+          cat << 'GH_AW_PROMPT_3c8a400b2f885ebf_EOF'
           </safe-output-tools>
           <github-context>
           The following GitHub context information is available for this workflow:
@@ -257,19 +283,23 @@ jobs:
           {{#if __GH_AW_GITHUB_RUN_ID__ }}
           - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
           {{/if}}
+          - **checkouts**: The following repositories have been checked out and are available in the workspace:
+            - `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: *]
+            - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
           </github-context>
           
-          GH_AW_PROMPT_EOF
+          GH_AW_PROMPT_3c8a400b2f885ebf_EOF
           cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
           if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
             cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md"
           fi
-          cat << 'GH_AW_PROMPT_EOF'
+          if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
+            cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_push_to_pr_branch_guidance.md"
+          fi
+          cat << 'GH_AW_PROMPT_3c8a400b2f885ebf_EOF'
           </system>
-          GH_AW_PROMPT_EOF
-          cat << 'GH_AW_PROMPT_EOF'
           {{#runtime-import .github/workflows/repo-assist.md}}
-          GH_AW_PROMPT_EOF
+          GH_AW_PROMPT_3c8a400b2f885ebf_EOF
           } > "$GH_AW_PROMPT"
       - name: Interpolate variables and render templates
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -343,19 +373,23 @@ jobs:
       - name: Validate prompt placeholders
         env:
           GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        # poutine:ignore untrusted_checkout_exec
         run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
       - name: Print prompt
         env:
           GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+        # poutine:ignore untrusted_checkout_exec
         run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
       - name: Upload activation artifact
         if: success()
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: activation
           path: |
             /tmp/gh-aw/aw_info.json
             /tmp/gh-aw/aw-prompts/prompt.txt
+            /tmp/gh-aw/github_rate_limits.jsonl
+          if-no-files-found: ignore
           retention-days: 1
 
   agent:
@@ -371,33 +405,60 @@ jobs:
       GH_AW_WORKFLOW_ID_SANITIZED: repoassist
     outputs:
       checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
-      detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
-      detection_success: ${{ steps.detection_conclusion.outputs.success }}
+      effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
       has_patch: ${{ steps.collect_output.outputs.has_patch }}
       inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
       model: ${{ needs.activation.outputs.model }}
       output: ${{ steps.collect_output.outputs.output }}
       output_types: ${{ steps.collect_output.outputs.output_types }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
     steps:
       - name: Setup Scripts
-        uses: github/gh-aw-actions/setup@b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6 # v0.62.0
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
         with:
           destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
       - name: Set runtime paths
+        id: set-runtime-paths
         run: |
-          echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_ENV"
-          echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_ENV"
-          echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_ENV"
+          echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_OUTPUT"
+          echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_OUTPUT"
+          echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_OUTPUT"
       - name: Checkout repository
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           persist-credentials: false
+          fetch-depth: 0
+      - name: Fetch additional refs
+        env:
+          GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          header=$(printf "x-access-token:%s" "${GH_AW_FETCH_TOKEN}" | base64 -w 0)
+          git -c "http.extraheader=Authorization: Basic ${header}" fetch origin '+refs/heads/*:refs/remotes/origin/*'
       - name: Create gh-aw temp directory
         run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
       - name: Configure gh CLI for GitHub Enterprise
         run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
         env:
           GH_TOKEN: ${{ github.token }}
+      - name: Start DIFC proxy for pre-agent gh calls
+        env:
+          GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          DIFC_PROXY_POLICY: '{"allow-only":{"min-integrity":"none","repos":"all"}}'
+          DIFC_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.2.14'
+        run: |
+          bash ${RUNNER_TEMP}/gh-aw/actions/start_difc_proxy.sh
+      - name: Set GH_REPO for proxied steps
+        run: |
+          echo "GH_REPO=${GITHUB_REPOSITORY}" >> "$GITHUB_ENV"
+      - env:
+          GH_TOKEN: ${{ github.token }}
+        name: Fetch repo data for task weighting
+        run: "mkdir -p /tmp/gh-aw\n\n# Fetch open issues with labels (up to 500)\ngh issue list --state open --limit 500 --json number,labels > /tmp/gh-aw/issues.json\n\n# Fetch open PRs with titles (up to 200)\ngh pr list --state open --limit 200 --json number,title > /tmp/gh-aw/prs.json\n\n# Compute task weights and select two tasks for this run\npython3 - << 'EOF'\nimport json, random, os\n\nwith open('/tmp/gh-aw/issues.json') as f:\n    issues = json.load(f)\nwith open('/tmp/gh-aw/prs.json') as f:\n    prs = json.load(f)\n\nopen_issues     = len(issues)\nunlabelled      = sum(1 for i in issues if not i.get('labels'))\nrepo_assist_prs = sum(1 for p in prs if p['title'].startswith('[Repo Assist]'))\nother_prs       = sum(1 for p in prs if not p['title'].startswith('[Repo Assist]'))\n\ntask_names = {\n    1:  'Issue Labelling',\n    2:  'Issue Investigation and Comment',\n    3:  'Issue Investigation and Fix',\n    4:  'Engineering Investments',\n    5:  'Coding Improvements',\n    6:  'Maintain Repo Assist PRs',\n    7:  'Stale PR Nudges',\n    8:  'Performance Improvements',\n    9:  'Testing Improvements',\n    10: 'Take the Repository Forward',\n}\n\nweights = {\n    1:  1   + 3 * unlabelled,\n    2:  3   + 1 * open_issues,\n    3:  3   + 0.7 * open_issues,\n    4:  5   + 0.2 * open_issues,\n    5:  5   + 0.1 * open_issues,\n    6:  float(repo_assist_prs),\n    7:  0.1 * other_prs,\n    8:  3   + 0.05 * open_issues,\n    9:  3   + 0.05 * open_issues,\n    10: 3   + 0.05 * open_issues,\n}\n\n# Seed with run ID for reproducibility within a run\nrun_id = int(os.environ.get('GITHUB_RUN_ID', '0'))\nrng = random.Random(run_id)\n\ntask_ids     = list(weights.keys())\ntask_weights = [weights[t] for t in task_ids]\n\n# Weighted sample without replacement (pick 2 distinct tasks)\nchosen, seen = [], set()\nfor t in rng.choices(task_ids, weights=task_weights, k=30):\n    if t not in seen:\n        seen.add(t)\n        chosen.append(t)\n    if len(chosen) == 2:\n        break\n\nprint('=== Repo Assist Task Selection ===')\nprint(f'Open issues       : {open_issues}')\nprint(f'Unlabelled issues : {unlabelled}')\nprint(f'Repo Assist PRs   : {repo_assist_prs}')\nprint(f'Other open PRs    : {other_prs}')\nprint()\nprint('Task weights:')\nfor t, w in weights.items():\n    tag = ' <-- SELECTED' if t in chosen else ''\n    print(f'  Task {t:2d} ({task_names[t]}): weight {w:6.1f}{tag}')\nprint()\nprint(f'Selected tasks for this run: Task {chosen[0]} ({task_names[chosen[0]]}) and Task {chosen[1]} ({task_names[chosen[1]]})')\n\nresult = {\n    'open_issues': open_issues, 'unlabelled_issues': unlabelled,\n    'repo_assist_prs': repo_assist_prs, 'other_prs': other_prs,\n    'task_names': task_names,\n    'weights': {str(k): round(v, 2) for k, v in weights.items()},\n    'selected_tasks': chosen,\n}\nwith open('/tmp/gh-aw/task_selection.json', 'w') as f:\n    json.dump(result, f, indent=2)\nEOF\n"
+
       # Repo memory git-based storage configuration from frontmatter processed below
       - name: Clone repo-memory branch (default)
         env:
@@ -412,18 +473,19 @@ jobs:
         env:
           REPO_NAME: ${{ github.repository }}
           SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
         run: |
           git config --global user.email "github-actions[bot]@users.noreply.github.com"
           git config --global user.name "github-actions[bot]"
           git config --global am.keepcr true
           # Re-authenticate git with GitHub token
           SERVER_URL_STRIPPED="${SERVER_URL#https://}"
-          git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
           echo "Git configured with standard GitHub Actions identity"
       - name: Checkout PR branch
         id: checkout-pr
         if: |
-          (github.event.pull_request) || (github.event.issue.pull_request)
+          github.event.pull_request || github.event.issue.pull_request
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
           GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -439,42 +501,46 @@ jobs:
         env:
           GH_HOST: github.com
       - name: Install AWF binary
-        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.24.3
-      - name: Determine automatic lockdown mode for GitHub MCP Server
-        id: determine-automatic-lockdown
-        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13
+      - name: Parse integrity filter lists
+        id: parse-guard-vars
         env:
-          GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
-          GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
-        with:
-          script: |
-            const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
-            await determineAutomaticLockdown(github, context, core);
+          GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+          GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+          GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh
+      - name: Stop DIFC proxy
+        if: always()
+        continue-on-error: true
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/stop_difc_proxy.sh
       - name: Download container images
-        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.3 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.3 ghcr.io/github/gh-aw-firewall/squid:0.24.3 ghcr.io/github/gh-aw-mcpg:v0.1.19 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.14 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
       - name: Write Safe Outputs Config
         run: |
           mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
           mkdir -p /tmp/gh-aw/safeoutputs
           mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
-          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
-          {"add_comment":{"max":10,"target":"*"},"add_labels":{"allowed":["AI-thinks-issue-fixed","AI-thinks-windows-only"],"max":30,"target":"*"},"create_issue":{"max":4},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":10240,"max_patch_size":10240}]},"update_issue":{"max":1}}
-          GH_AW_SAFE_OUTPUTS_CONFIG_EOF
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_864b571330e86582_EOF'
+          {"add_comment":{"hide_older_comments":true,"max":10,"target":"*"},"add_labels":{"allowed":["AI-thinks-issue-fixed","AI-thinks-windows-only"],"max":30,"target":"*"},"create_issue":{"labels":["automation","repo-assist"],"max":4,"title_prefix":"[Repo Assist] "},"create_pull_request":{"allowed_files":["tests/**","vsintegration/tests/**"],"auto_merge":true,"draft":false,"labels":["NO_RELEASE_NOTES","AI-Issue-Regression-PR"],"max":10,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_path_prefixes":[".github/",".agents/"],"reviewers":["abonie","T-Gro"],"title_prefix":"Add regression test: "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":10240,"max_patch_size":10240}]},"push_to_pull_request_branch":{"if_no_changes":"warn","max":4,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_files_policy":"fallback-to-issue","protected_path_prefixes":[".github/",".agents/"],"target":"*","title_prefix":"[Repo Assist] "},"remove_labels":{"allowed":["AI-thinks-issue-fixed","AI-thinks-windows-only"],"max":10,"target":"*"},"report_incomplete":{},"update_issue":{"allow_body":true,"max":1,"target":"*","title_prefix":"[Repo Assist] "}}
+          GH_AW_SAFE_OUTPUTS_CONFIG_864b571330e86582_EOF
       - name: Write Safe Outputs Tools
         run: |
-          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF'
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_de21273092ddd64e_EOF'
           {
             "description_suffixes": {
               "add_comment": " CONSTRAINTS: Maximum 10 comment(s) can be added. Target: *.",
               "add_labels": " CONSTRAINTS: Maximum 30 label(s) can be added. Only these labels are allowed: [\"AI-thinks-issue-fixed\" \"AI-thinks-windows-only\"]. Target: *.",
               "create_issue": " CONSTRAINTS: Maximum 4 issue(s) can be created. Title will be prefixed with \"[Repo Assist] \". Labels [\"automation\" \"repo-assist\"] will be automatically added.",
+              "create_pull_request": " CONSTRAINTS: Maximum 10 pull request(s) can be created. Title will be prefixed with \"Add regression test: \". Labels [\"NO_RELEASE_NOTES\" \"AI-Issue-Regression-PR\"] will be automatically added. Reviewers [\"abonie\" \"T-Gro\"] will be assigned.",
+              "push_to_pull_request_branch": " CONSTRAINTS: Maximum 4 push(es) can be made. The target pull request title must start with \"[Repo Assist] \".",
+              "remove_labels": " CONSTRAINTS: Maximum 10 label(s) can be removed. Only these labels can be removed: [AI-thinks-issue-fixed AI-thinks-windows-only]. Target: *.",
               "update_issue": " CONSTRAINTS: Maximum 1 issue(s) can be updated. Target: *. The target issue title must start with \"[Repo Assist] \"."
             },
             "repo_params": {},
             "dynamic_tools": []
           }
-          GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF
-          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
+          GH_AW_SAFE_OUTPUTS_TOOLS_META_de21273092ddd64e_EOF
+          cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_04b2a5f431edb6bf_EOF'
           {
             "add_comment": {
               "defaultMax": 1,
@@ -546,6 +612,42 @@ jobs:
                 }
               }
             },
+            "create_pull_request": {
+              "defaultMax": 1,
+              "fields": {
+                "body": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "branch": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "draft": {
+                  "type": "boolean"
+                },
+                "labels": {
+                  "type": "array",
+                  "itemType": "string",
+                  "itemSanitize": true,
+                  "itemMaxLength": 128
+                },
+                "repo": {
+                  "type": "string",
+                  "maxLength": 256
+                },
+                "title": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 128
+                }
+              }
+            },
             "missing_data": {
               "defaultMax": 20,
               "fields": {
@@ -603,6 +705,61 @@ jobs:
                 }
               }
             },
+            "push_to_pull_request_branch": {
+              "defaultMax": 1,
+              "fields": {
+                "branch": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 256
+                },
+                "message": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "pull_request_number": {
+                  "issueOrPRNumber": true
+                }
+              }
+            },
+            "remove_labels": {
+              "defaultMax": 5,
+              "fields": {
+                "item_number": {
+                  "issueNumberOrTemporaryId": true
+                },
+                "labels": {
+                  "required": true,
+                  "type": "array",
+                  "itemType": "string",
+                  "itemSanitize": true,
+                  "itemMaxLength": 128
+                },
+                "repo": {
+                  "type": "string",
+                  "maxLength": 256
+                }
+              }
+            },
+            "report_incomplete": {
+              "defaultMax": 5,
+              "fields": {
+                "details": {
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 65000
+                },
+                "reason": {
+                  "required": true,
+                  "type": "string",
+                  "sanitize": true,
+                  "maxLength": 1024
+                }
+              }
+            },
             "update_issue": {
               "defaultMax": 1,
               "fields": {
@@ -658,7 +815,7 @@ jobs:
               "customValidation": "requiresOneOf:status,title,body"
             }
           }
-          GH_AW_SAFE_OUTPUTS_VALIDATION_EOF
+          GH_AW_SAFE_OUTPUTS_VALIDATION_04b2a5f431edb6bf_EOF
           node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
       - name: Generate Safe Outputs MCP Server Config
         id: safe-outputs-config
@@ -682,6 +839,7 @@ jobs:
         id: safe-outputs-start
         env:
           DEBUG: '*'
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
           GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
           GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
           GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
@@ -690,6 +848,7 @@ jobs:
         run: |
           # Environment variables are set above to prevent template injection
           export DEBUG
+          export GH_AW_SAFE_OUTPUTS
           export GH_AW_SAFE_OUTPUTS_PORT
           export GH_AW_SAFE_OUTPUTS_API_KEY
           export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
@@ -701,11 +860,9 @@ jobs:
       - name: Start MCP Gateway
         id: start-mcp-gateway
         env:
-          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
           GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
           GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
-          GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
-          GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
           GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
         run: |
           set -eo pipefail
@@ -723,10 +880,10 @@ jobs:
           export DEBUG="*"
           
           export GH_AW_ENGINE="copilot"
-          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.19'
+          export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.14'
           
           mkdir -p /home/runner/.copilot
-          cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
+          cat << GH_AW_MCP_CONFIG_01285a2b2c6a7d4e_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
           {
             "mcpServers": {
               "github": {
@@ -740,8 +897,11 @@ jobs:
                 },
                 "guard-policies": {
                   "allow-only": {
-                    "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
-                    "repos": "$GITHUB_MCP_GUARD_REPOS"
+                    "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+                    "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+                    "min-integrity": "none",
+                    "repos": "all",
+                    "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
                   }
                 }
               },
@@ -767,7 +927,7 @@ jobs:
               "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
             }
           }
-          GH_AW_MCP_CONFIG_EOF
+          GH_AW_MCP_CONFIG_01285a2b2c6a7d4e_EOF
       - name: Download activation artifact
         uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
         with:
@@ -784,8 +944,8 @@ jobs:
           set -o pipefail
           touch /tmp/gh-aw/agent-step-summary.md
           # shellcheck disable=SC1003
-          sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --allow-domains "*.pythonhosted.org,*.vsblob.vsassets.io,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.3 --skip-pull --enable-api-proxy \
-            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+          sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.pythonhosted.org,*.vsblob.vsassets.io,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
         env:
           COPILOT_AGENT_RUNNER_TYPE: STANDALONE
           COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
@@ -793,8 +953,8 @@ jobs:
           GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
           GH_AW_PHASE: agent
           GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
-          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
-          GH_AW_VERSION: v0.62.0
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_VERSION: v0.67.1
           GITHUB_API_URL: ${{ github.api_url }}
           GITHUB_AW: true
           GITHUB_HEAD_REF: ${{ github.head_ref }}
@@ -817,31 +977,19 @@ jobs:
         env:
           REPO_NAME: ${{ github.repository }}
           SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
         run: |
           git config --global user.email "github-actions[bot]@users.noreply.github.com"
           git config --global user.name "github-actions[bot]"
           git config --global am.keepcr true
           # Re-authenticate git with GitHub token
           SERVER_URL_STRIPPED="${SERVER_URL#https://}"
-          git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
           echo "Git configured with standard GitHub Actions identity"
       - name: Copy Copilot session state files to logs
         if: always()
         continue-on-error: true
-        run: |
-          # Copy Copilot session state files to logs folder for artifact collection
-          # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them
-          SESSION_STATE_DIR="$HOME/.copilot/session-state"
-          LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs"
-          
-          if [ -d "$SESSION_STATE_DIR" ]; then
-            echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR"
-            mkdir -p "$LOGS_DIR"
-            cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true
-            echo "Session state files copied successfully"
-          else
-            echo "No session-state directory found at $SESSION_STATE_DIR"
-          fi
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh
       - name: Stop MCP Gateway
         if: always()
         continue-on-error: true
@@ -871,6 +1019,8 @@ jobs:
         run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
       - name: Copy Safe Outputs
         if: always()
+        env:
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
         run: |
           mkdir -p /tmp/gh-aw
           cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
@@ -879,7 +1029,7 @@ jobs:
         if: always()
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
+          GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
           GH_AW_ALLOWED_DOMAINS: "*.pythonhosted.org,*.vsblob.vsassets.io,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com"
           GITHUB_SERVER_URL: ${{ github.server_url }}
           GITHUB_API_URL: ${{ github.api_url }}
@@ -903,6 +1053,7 @@ jobs:
             await main();
       - name: Parse MCP Gateway logs for step summary
         if: always()
+        id: parse-mcp-gateway
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         with:
           script: |
@@ -925,10 +1076,26 @@ jobs:
           else
             echo 'AWF binary not installed, skipping firewall log summary'
           fi
+      - name: Parse token usage for step summary
+        if: always()
+        continue-on-error: true
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
+            await main();
+      - name: Write agent output placeholder if missing
+        if: always()
+        run: |
+          if [ ! -f /tmp/gh-aw/agent_output.json ]; then
+            echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
+          fi
       # Upload repo memory as artifacts for push job
       - name: Upload repo-memory artifact (default)
         if: always()
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: repo-memory-default
           path: /tmp/gh-aw/repo-memory/default
@@ -937,7 +1104,7 @@ jobs:
       - name: Upload agent artifacts
         if: always()
         continue-on-error: true
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: agent
           path: |
@@ -945,147 +1112,39 @@ jobs:
             /tmp/gh-aw/sandbox/agent/logs/
             /tmp/gh-aw/redacted-urls.log
             /tmp/gh-aw/mcp-logs/
-            /tmp/gh-aw/sandbox/firewall/logs/
+            /tmp/gh-aw/proxy-logs/
+            !/tmp/gh-aw/proxy-logs/proxy-tls/
+            /tmp/gh-aw/agent_usage.json
             /tmp/gh-aw/agent-stdio.log
             /tmp/gh-aw/agent/
+            /tmp/gh-aw/github_rate_limits.jsonl
             /tmp/gh-aw/safeoutputs.jsonl
             /tmp/gh-aw/agent_output.json
+            /tmp/gh-aw/aw-*.patch
+            /tmp/gh-aw/aw-*.bundle
           if-no-files-found: ignore
-      # --- Threat Detection (inline) ---
-      - name: Check if detection needed
-        id: detection_guard
+      - name: Upload firewall audit logs
         if: always()
-        env:
-          OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
-          HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
-        run: |
-          if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
-            echo "run_detection=true" >> "$GITHUB_OUTPUT"
-            echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
-          else
-            echo "run_detection=false" >> "$GITHUB_OUTPUT"
-            echo "Detection skipped: no agent outputs or patches to analyze"
-          fi
-      - name: Clear MCP configuration for detection
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        run: |
-          rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
-          rm -f /home/runner/.copilot/mcp-config.json
-          rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
-      - name: Prepare threat detection files
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        run: |
-          mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
-          cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
-          cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
-          for f in /tmp/gh-aw/aw-*.patch; do
-            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
-          done
-          echo "Prepared threat detection files:"
-          ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
-      - name: Setup threat detection
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
-        env:
-          WORKFLOW_NAME: "Repo Assist"
-          WORKFLOW_DESCRIPTION: "A friendly repository assistant that runs 4 times a day to support contributors and maintainers.\nCan also be triggered on-demand via '/repo-assist <instructions>' to perform specific tasks.\n- Labels and triages open issues\n- Comments helpfully on open issues to unblock contributors and onboard newcomers\n- Identifies issues that can be fixed and creates draft pull requests with fixes\n- Improves performance, testing, and code quality via PRs\n- Makes engineering investments: dependency updates, CI improvements, tooling\n- Updates its own PRs when CI fails or merge conflicts arise\n- Nudges stale PRs waiting for author response\n- Takes the repository forward with proactive improvements\n- Maintains a persistent memory of work done and what remains\nAlways polite, constructive, and mindful of the project's goals."
-          HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
-        with:
-          script: |
-            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
-            setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
-            await main();
-      - name: Ensure threat-detection directory and log
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        run: |
-          mkdir -p /tmp/gh-aw/threat-detection
-          touch /tmp/gh-aw/threat-detection/detection.log
-      - name: Execute GitHub Copilot CLI
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        id: detection_agentic_execution
-        # Copilot CLI tool arguments (sorted):
-        # --allow-tool shell(cat)
-        # --allow-tool shell(grep)
-        # --allow-tool shell(head)
-        # --allow-tool shell(jq)
-        # --allow-tool shell(ls)
-        # --allow-tool shell(tail)
-        # --allow-tool shell(wc)
-        timeout-minutes: 20
-        run: |
-          set -o pipefail
-          touch /tmp/gh-aw/agent-step-summary.md
-          # shellcheck disable=SC1003
-          sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.3 --skip-pull --enable-api-proxy \
-            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
-        env:
-          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
-          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
-          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
-          GH_AW_PHASE: detection
-          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
-          GH_AW_VERSION: v0.62.0
-          GITHUB_API_URL: ${{ github.api_url }}
-          GITHUB_AW: true
-          GITHUB_HEAD_REF: ${{ github.head_ref }}
-          GITHUB_REF_NAME: ${{ github.ref_name }}
-          GITHUB_SERVER_URL: ${{ github.server_url }}
-          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
-          GITHUB_WORKSPACE: ${{ github.workspace }}
-          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
-          GIT_AUTHOR_NAME: github-actions[bot]
-          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
-          GIT_COMMITTER_NAME: github-actions[bot]
-          XDG_CONFIG_HOME: /home/runner
-      - name: Parse threat detection results
-        id: parse_detection_results
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
-        with:
-          script: |
-            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
-            setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
-            await main();
-      - name: Upload threat detection log
-        if: always() && steps.detection_guard.outputs.run_detection == 'true'
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        continue-on-error: true
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
-          name: detection
-          path: /tmp/gh-aw/threat-detection/detection.log
+          name: firewall-audit-logs
+          path: |
+            /tmp/gh-aw/sandbox/firewall/logs/
+            /tmp/gh-aw/sandbox/firewall/audit/
           if-no-files-found: ignore
-      - name: Set detection conclusion
-        id: detection_conclusion
-        if: always()
-        env:
-          RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
-          DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
-        run: |
-          if [[ "$RUN_DETECTION" != "true" ]]; then
-            echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
-            echo "success=true" >> "$GITHUB_OUTPUT"
-            echo "Detection was not needed, marking as skipped"
-          elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
-            echo "conclusion=success" >> "$GITHUB_OUTPUT"
-            echo "success=true" >> "$GITHUB_OUTPUT"
-            echo "Detection passed successfully"
-          else
-            echo "conclusion=failure" >> "$GITHUB_OUTPUT"
-            echo "success=false" >> "$GITHUB_OUTPUT"
-            echo "Detection found issues"
-          fi
 
   conclusion:
     needs:
       - activation
       - agent
+      - detection
       - push_repo_memory
       - safe_outputs
-    if: (always()) && ((needs.agent.result != 'skipped') || (needs.activation.outputs.lockdown_check_failed == 'true'))
+    if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
     runs-on: ubuntu-slim
     permissions:
-      contents: read
+      contents: write
       discussions: write
       issues: write
       pull-requests: write
@@ -1093,14 +1152,18 @@ jobs:
       group: "gh-aw-conclusion-repo-assist"
       cancel-in-progress: false
     outputs:
+      incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
       noop_message: ${{ steps.noop.outputs.noop_message }}
       tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
       total_count: ${{ steps.missing_tool.outputs.total_count }}
     steps:
       - name: Setup Scripts
-        uses: github/gh-aw-actions/setup@b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6 # v0.62.0
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
         with:
           destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
       - name: Download agent output artifact
         id: download-agent-output
         continue-on-error: true
@@ -1109,35 +1172,40 @@ jobs:
           name: agent
           path: /tmp/gh-aw/
       - name: Setup agent output environment variable
+        id: setup-agent-output-env
         if: steps.download-agent-output.outcome == 'success'
         run: |
           mkdir -p /tmp/gh-aw/
           find "/tmp/gh-aw/" -type f -print
-          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
       - name: Process No-Op Messages
         id: noop
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
           GH_AW_NOOP_MAX: "1"
           GH_AW_WORKFLOW_NAME: "Repo Assist"
-          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02"
-          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/9135cdfde26838a01779aa966628308404ec1f02/workflows/repo-assist.md"
+          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404"
+          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/7c7feb61a52b662eb2089aa2945588b7a200d404/workflows/repo-assist.md"
+          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+          GH_AW_NOOP_REPORT_AS_ISSUE: "true"
         with:
           github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
           script: |
             const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
             setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/noop.cjs');
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
             await main();
       - name: Record Missing Tool
         id: missing_tool
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
           GH_AW_WORKFLOW_NAME: "Repo Assist"
-          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02"
-          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/9135cdfde26838a01779aa966628308404ec1f02/workflows/repo-assist.md"
+          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404"
+          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/7c7feb61a52b662eb2089aa2945588b7a200d404/workflows/repo-assist.md"
         with:
           github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
           script: |
@@ -1145,22 +1213,42 @@ jobs:
             setupGlobals(core, github, context, exec, io);
             const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
             await main();
+      - name: Record Incomplete
+        id: report_incomplete
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
+          GH_AW_WORKFLOW_NAME: "Repo Assist"
+          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404"
+          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/7c7feb61a52b662eb2089aa2945588b7a200d404/workflows/repo-assist.md"
+        with:
+          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
+            await main();
       - name: Handle Agent Failure
         id: handle_agent_failure
         if: always()
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
           GH_AW_WORKFLOW_NAME: "Repo Assist"
-          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02"
-          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/9135cdfde26838a01779aa966628308404ec1f02/workflows/repo-assist.md"
+          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404"
+          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/7c7feb61a52b662eb2089aa2945588b7a200d404/workflows/repo-assist.md"
           GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
           GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
           GH_AW_WORKFLOW_ID: "repo-assist"
+          GH_AW_ENGINE_ID: "copilot"
           GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
           GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
           GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+          GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
+          GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
           GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+          GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e Generated by 🌈 {workflow_name}, see [workflow run]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md).\",\"runStarted\":\"{workflow_name} is processing {event_type}, see [workflow run]({run_url})...\",\"runSuccess\":\"✓ {workflow_name} completed successfully, see [workflow run]({run_url}).\",\"runFailure\":\"✗ {workflow_name} encountered {status}, see [workflow run]({run_url}).\"}"
           GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }}
           GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }}
           GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }}
@@ -1175,74 +1263,195 @@ jobs:
             setupGlobals(core, github, context, exec, io);
             const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
             await main();
-      - name: Handle No-Op Message
-        id: handle_noop_message
+      - name: Update reaction comment with completion status
+        id: conclusion
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
-          GH_AW_WORKFLOW_NAME: "Repo Assist"
-          GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02"
-          GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/9135cdfde26838a01779aa966628308404ec1f02/workflows/repo-assist.md"
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+          GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
+          GH_AW_COMMENT_REPO: ${{ needs.activation.outputs.comment_repo }}
           GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+          GH_AW_WORKFLOW_NAME: "Repo Assist"
           GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
-          GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }}
-          GH_AW_NOOP_REPORT_AS_ISSUE: "true"
+          GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+          GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e Generated by 🌈 {workflow_name}, see [workflow run]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md).\",\"runStarted\":\"{workflow_name} is processing {event_type}, see [workflow run]({run_url})...\",\"runSuccess\":\"✓ {workflow_name} completed successfully, see [workflow run]({run_url}).\",\"runFailure\":\"✗ {workflow_name} encountered {status}, see [workflow run]({run_url}).\"}"
         with:
           github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
           script: |
             const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
             setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/notify_comment_error.cjs');
             await main();
-      - name: Update reaction comment with completion status
-        id: conclusion
+
+  detection:
+    needs:
+      - activation
+      - agent
+    if: >
+      always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+    outputs:
+      detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+      detection_success: ${{ steps.detection_conclusion.outputs.success }}
+    steps:
+      - name: Setup Scripts
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
+        with:
+          destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+      - name: Download agent output artifact
+        id: download-agent-output
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Setup agent output environment variable
+        id: setup-agent-output-env
+        if: steps.download-agent-output.outcome == 'success'
+        run: |
+          mkdir -p /tmp/gh-aw/
+          find "/tmp/gh-aw/" -type f -print
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Checkout repository for patch context
+        if: needs.agent.outputs.has_patch == 'true'
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+      # --- Threat Detection ---
+      - name: Download container images
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13
+      - name: Check if detection needed
+        id: detection_guard
+        if: always()
+        env:
+          OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
+          HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+        run: |
+          if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+            echo "run_detection=true" >> "$GITHUB_OUTPUT"
+            echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+          else
+            echo "run_detection=false" >> "$GITHUB_OUTPUT"
+            echo "Detection skipped: no agent outputs or patches to analyze"
+          fi
+      - name: Clear MCP configuration for detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
+          rm -f /home/runner/.copilot/mcp-config.json
+          rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+      - name: Prepare threat detection files
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
+          cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
+          cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
+          for f in /tmp/gh-aw/aw-*.patch; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          for f in /tmp/gh-aw/aw-*.bundle; do
+            [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+          done
+          echo "Prepared threat detection files:"
+          ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+      - name: Setup threat detection
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
-          GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
-          GH_AW_COMMENT_REPO: ${{ needs.activation.outputs.comment_repo }}
-          GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
-          GH_AW_WORKFLOW_NAME: "Repo Assist"
-          GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
-          GH_AW_DETECTION_CONCLUSION: ${{ needs.agent.outputs.detection_conclusion }}
+          WORKFLOW_NAME: "Repo Assist"
+          WORKFLOW_DESCRIPTION: "A friendly repository assistant that runs 2 times a day to support contributors and maintainers.\nCan also be triggered on-demand via '/repo-assist <instructions>' to perform specific tasks.\n- Labels and triages open issues\n- Comments helpfully on open issues to unblock contributors and onboard newcomers\n- Identifies issues that can be fixed and creates draft pull requests with fixes\n- Improves performance, testing, and code quality via PRs\n- Makes engineering investments: dependency updates, CI improvements, tooling\n- Updates its own PRs when CI fails or merge conflicts arise\n- Nudges stale PRs waiting for author response\n- Takes the repository forward with proactive improvements\n- Maintains a persistent memory of work done and what remains\nAlways polite, constructive, and mindful of the project's goals."
+          HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
         with:
-          github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
           script: |
             const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
             setupGlobals(core, github, context, exec, io);
-            const { main } = require('${{ runner.temp }}/gh-aw/actions/notify_comment_error.cjs');
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
+            await main();
+      - name: Ensure threat-detection directory and log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        run: |
+          mkdir -p /tmp/gh-aw/threat-detection
+          touch /tmp/gh-aw/threat-detection/detection.log
+      - name: Install GitHub Copilot CLI
+        run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
+        env:
+          GH_HOST: github.com
+      - name: Install AWF binary
+        run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13
+      - name: Execute GitHub Copilot CLI
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        id: detection_agentic_execution
+        # Copilot CLI tool arguments (sorted):
+        timeout-minutes: 20
+        run: |
+          set -o pipefail
+          touch /tmp/gh-aw/agent-step-summary.md
+          # shellcheck disable=SC1003
+          sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \
+            -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+        env:
+          COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+          COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+          COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
+          GH_AW_PHASE: detection
+          GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+          GH_AW_VERSION: v0.67.1
+          GITHUB_API_URL: ${{ github.api_url }}
+          GITHUB_AW: true
+          GITHUB_HEAD_REF: ${{ github.head_ref }}
+          GITHUB_REF_NAME: ${{ github.ref_name }}
+          GITHUB_SERVER_URL: ${{ github.server_url }}
+          GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_AUTHOR_NAME: github-actions[bot]
+          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+          GIT_COMMITTER_NAME: github-actions[bot]
+          XDG_CONFIG_HOME: /home/runner
+      - name: Upload threat detection log
+        if: always() && steps.detection_guard.outputs.run_detection == 'true'
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
+        with:
+          name: detection
+          path: /tmp/gh-aw/threat-detection/detection.log
+          if-no-files-found: ignore
+      - name: Parse and conclude threat detection
+        id: detection_conclusion
+        if: always()
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+        env:
+          RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+        with:
+          script: |
+            const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+            setupGlobals(core, github, context, exec, io);
+            const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
             await main();
 
   pre_activation:
-    if: >
-      ((github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request' ||
-      github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment') &&
-      ((github.event_name == 'issues') && ((startsWith(github.event.issue.body, '/repo-assist ')) || (github.event.issue.body == '/repo-assist')) ||
-      (github.event_name == 'issue_comment') && (((startsWith(github.event.comment.body, '/repo-assist ')) ||
-      (github.event.comment.body == '/repo-assist')) && (github.event.issue.pull_request == null)) || (github.event_name == 'issue_comment') &&
-      (((startsWith(github.event.comment.body, '/repo-assist ')) || (github.event.comment.body == '/repo-assist')) &&
-      (github.event.issue.pull_request != null)) || (github.event_name == 'pull_request_review_comment') &&
-      ((startsWith(github.event.comment.body, '/repo-assist ')) || (github.event.comment.body == '/repo-assist')) ||
-      (github.event_name == 'pull_request') && ((startsWith(github.event.pull_request.body, '/repo-assist ')) ||
-      (github.event.pull_request.body == '/repo-assist')) || (github.event_name == 'discussion') && ((startsWith(github.event.discussion.body, '/repo-assist ')) ||
-      (github.event.discussion.body == '/repo-assist')) || (github.event_name == 'discussion_comment') && ((startsWith(github.event.comment.body, '/repo-assist ')) ||
-      (github.event.comment.body == '/repo-assist')))) || (!(github.event_name == 'issues' || github.event_name == 'issue_comment' ||
-      github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' ||
-      github.event_name == 'discussion_comment'))
+    if: "(github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment') && (github.event_name == 'issues' && (startsWith(github.event.issue.body, '/repo-assist ') || startsWith(github.event.issue.body, '/repo-assist\n') || github.event.issue.body == '/repo-assist') || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request == null || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request != null || github.event_name == 'pull_request_review_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') || github.event_name == 'pull_request' && (startsWith(github.event.pull_request.body, '/repo-assist ') || startsWith(github.event.pull_request.body, '/repo-assist\n') || github.event.pull_request.body == '/repo-assist') || github.event_name == 'discussion' && (startsWith(github.event.discussion.body, '/repo-assist ') || startsWith(github.event.discussion.body, '/repo-assist\n') || github.event.discussion.body == '/repo-assist') || github.event_name == 'discussion_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist')) || (!(github.event_name == 'issues')) && (!(github.event_name == 'issue_comment')) && (!(github.event_name == 'pull_request')) && (!(github.event_name == 'pull_request_review_comment')) && (!(github.event_name == 'discussion')) && (!(github.event_name == 'discussion_comment'))"
     runs-on: ubuntu-slim
     outputs:
-      activated: ${{ (steps.check_membership.outputs.is_team_member == 'true') && (steps.check_command_position.outputs.command_position_ok == 'true') }}
+      activated: ${{ steps.check_membership.outputs.is_team_member == 'true' && steps.check_command_position.outputs.command_position_ok == 'true' }}
       matched_command: ${{ steps.check_command_position.outputs.matched_command }}
+      setup-trace-id: ${{ steps.setup.outputs.trace-id }}
     steps:
       - name: Setup Scripts
-        uses: github/gh-aw-actions/setup@b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6 # v0.62.0
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
         with:
           destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
       - name: Check team membership for command workflow
         id: check_membership
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_REQUIRED_ROLES: admin,maintainer,write
+          GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
         with:
           github-token: ${{ secrets.GITHUB_TOKEN }}
           script: |
@@ -1263,13 +1472,18 @@ jobs:
             await main();
 
   push_repo_memory:
-    needs: agent
-    if: always() && needs.agent.outputs.detection_success == 'true'
-    runs-on: ubuntu-latest
+    needs:
+      - activation
+      - agent
+      - detection
+    if: >
+      always() && (needs.detection.result == 'success' || needs.detection.result == 'skipped') &&
+      needs.agent.result == 'success'
+    runs-on: ubuntu-slim
     permissions:
       contents: write
     concurrency:
-      group: "push-repo-memory-${{ github.repository }}"
+      group: "push-repo-memory-${{ github.repository }}|memory/repo-assist"
       cancel-in-progress: false
     outputs:
       patch_size_exceeded_default: ${{ steps.push_repo_memory_default.outputs.patch_size_exceeded }}
@@ -1277,9 +1491,12 @@ jobs:
       validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }}
     steps:
       - name: Setup Scripts
-        uses: github/gh-aw-actions/setup@b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6 # v0.62.0
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
         with:
           destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
       - name: Checkout repository
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
@@ -1289,13 +1506,14 @@ jobs:
         env:
           REPO_NAME: ${{ github.repository }}
           SERVER_URL: ${{ github.server_url }}
+          GITHUB_TOKEN: ${{ github.token }}
         run: |
           git config --global user.email "github-actions[bot]@users.noreply.github.com"
           git config --global user.name "github-actions[bot]"
           git config --global am.keepcr true
           # Re-authenticate git with GitHub token
           SERVER_URL_STRIPPED="${SERVER_URL#https://}"
-          git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
           echo "Git configured with standard GitHub Actions identity"
       - name: Download repo-memory artifact (default)
         uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -1327,22 +1545,28 @@ jobs:
             await main();
 
   safe_outputs:
-    needs: agent
-    if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.agent.outputs.detection_success == 'true')
+    needs:
+      - activation
+      - agent
+      - detection
+    if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
     runs-on: ubuntu-slim
     permissions:
-      contents: read
+      contents: write
       discussions: write
       issues: write
       pull-requests: write
     timeout-minutes: 15
     env:
       GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/repo-assist"
+      GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
       GH_AW_ENGINE_ID: "copilot"
+      GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+      GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e Generated by 🌈 {workflow_name}, see [workflow run]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md).\",\"runStarted\":\"{workflow_name} is processing {event_type}, see [workflow run]({run_url})...\",\"runSuccess\":\"✓ {workflow_name} completed successfully, see [workflow run]({run_url}).\",\"runFailure\":\"✗ {workflow_name} encountered {status}, see [workflow run]({run_url}).\"}"
       GH_AW_WORKFLOW_ID: "repo-assist"
       GH_AW_WORKFLOW_NAME: "Repo Assist"
-      GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02"
-      GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/9135cdfde26838a01779aa966628308404ec1f02/workflows/repo-assist.md"
+      GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404"
+      GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/7c7feb61a52b662eb2089aa2945588b7a200d404/workflows/repo-assist.md"
     outputs:
       code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
       code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
@@ -1352,13 +1576,20 @@ jobs:
       create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
       created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
       created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
+      created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
+      created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }}
       process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
       process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+      push_commit_sha: ${{ steps.process_safe_outputs.outputs.push_commit_sha }}
+      push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }}
     steps:
       - name: Setup Scripts
-        uses: github/gh-aw-actions/setup@b2c35f34e1013dd9ed2a84c559e2b2fec9ad38e6 # v0.62.0
+        id: setup
+        uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1
         with:
           destination: ${{ runner.temp }}/gh-aw/actions
+          job-name: ${{ github.job }}
+          trace-id: ${{ needs.activation.outputs.setup-trace-id }}
       - name: Download agent output artifact
         id: download-agent-output
         continue-on-error: true
@@ -1367,12 +1598,42 @@ jobs:
           name: agent
           path: /tmp/gh-aw/
       - name: Setup agent output environment variable
+        id: setup-agent-output-env
         if: steps.download-agent-output.outcome == 'success'
         run: |
           mkdir -p /tmp/gh-aw/
           find "/tmp/gh-aw/" -type f -print
-          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
+          echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+      - name: Download patch artifact
+        continue-on-error: true
+        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        with:
+          name: agent
+          path: /tmp/gh-aw/
+      - name: Checkout repository
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') || (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
+          token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+          persist-credentials: false
+          fetch-depth: 1
+      - name: Configure Git credentials
+        if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') || (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
+        env:
+          REPO_NAME: ${{ github.repository }}
+          SERVER_URL: ${{ github.server_url }}
+          GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+        run: |
+          git config --global user.email "github-actions[bot]@users.noreply.github.com"
+          git config --global user.name "github-actions[bot]"
+          git config --global am.keepcr true
+          # Re-authenticate git with GitHub token
+          SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+          git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+          echo "Git configured with standard GitHub Actions identity"
       - name: Configure GH_HOST for enterprise compatibility
+        id: ghes-host-config
         shell: bash
         run: |
           # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
@@ -1384,11 +1645,12 @@ jobs:
         id: process_safe_outputs
         uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
         env:
-          GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
+          GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
           GH_AW_ALLOWED_DOMAINS: "*.pythonhosted.org,*.vsblob.vsassets.io,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,dc.services.visualstudio.com,dist.nuget.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com"
           GITHUB_SERVER_URL: ${{ github.server_url }}
           GITHUB_API_URL: ${{ github.api_url }}
-          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":10,\"target\":\"*\"},\"add_labels\":{\"allowed\":[\"AI-thinks-issue-fixed\",\"AI-thinks-windows-only\"],\"max\":30,\"target\":\"*\"},\"create_issue\":{\"labels\":[\"automation\",\"repo-assist\"],\"max\":4,\"title_prefix\":\"[Repo Assist] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"update_issue\":{\"allow_body\":true,\"max\":1,\"target\":\"*\",\"title_prefix\":\"[Repo Assist] \"}}"
+          GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":10,\"target\":\"*\"},\"add_labels\":{\"allowed\":[\"AI-thinks-issue-fixed\",\"AI-thinks-windows-only\"],\"max\":30,\"target\":\"*\"},\"create_issue\":{\"labels\":[\"automation\",\"repo-assist\"],\"max\":4,\"title_prefix\":\"[Repo Assist] \"},\"create_pull_request\":{\"allowed_files\":[\"tests/**\",\"vsintegration/tests/**\"],\"auto_merge\":true,\"draft\":false,\"labels\":[\"NO_RELEASE_NOTES\",\"AI-Issue-Regression-PR\"],\"max\":10,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"reviewers\":[\"abonie\",\"T-Gro\"],\"title_prefix\":\"Add regression test: \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"max\":4,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_files_policy\":\"fallback-to-issue\",\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\",\"title_prefix\":\"[Repo Assist] \"},\"remove_labels\":{\"allowed\":[\"AI-thinks-issue-fixed\",\"AI-thinks-windows-only\"],\"max\":10,\"target\":\"*\"},\"report_incomplete\":{},\"update_issue\":{\"allow_body\":true,\"max\":1,\"target\":\"*\",\"title_prefix\":\"[Repo Assist] \"}}"
+          GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
         with:
           github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
           script: |
@@ -1396,11 +1658,11 @@ jobs:
             setupGlobals(core, github, context, exec, io);
             const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
             await main();
-      - name: Upload Safe Output Items Manifest
+      - name: Upload Safe Output Items
         if: always()
-        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
         with:
           name: safe-output-items
-          path: /tmp/safe-output-items.jsonl
-          if-no-files-found: warn
+          path: /tmp/gh-aw/safe-output-items.jsonl
+          if-no-files-found: ignore
 
diff --git a/.github/workflows/repo-assist.md b/.github/workflows/repo-assist.md
index ce426b23965..92719ee8a48 100644
--- a/.github/workflows/repo-assist.md
+++ b/.github/workflows/repo-assist.md
@@ -1,6 +1,6 @@
 ---
 description: |
-  A friendly repository assistant that runs 4 times a day to support contributors and maintainers.
+  A friendly repository assistant that runs 2 times a day to support contributors and maintainers.
   Can also be triggered on-demand via '/repo-assist <instructions>' to perform specific tasks.
   - Labels and triages open issues
   - Comments helpfully on open issues to unblock contributors and onboard newcomers
@@ -14,7 +14,7 @@ description: |
   Always polite, constructive, and mindful of the project's goals.
 
 on:
-  schedule: every 6h
+  schedule: every 12h
   workflow_dispatch:
   slash_command:
     name: repo-assist
@@ -30,21 +30,41 @@ network:
   - dotnet
   - python
 
+checkout:
+  fetch: ["*"]     # fetch all remote branches to allow working on PR branches
+  fetch-depth: 0   # fetch full history
+
+tools:
+  web-fetch:
+  github:
+    toolsets: [all]
+    min-integrity: none # This workflow is allowed to examine and comment on any issues or PRs
+  bash: true
+  repo-memory: true
+
 safe-outputs:
+  messages:
+    footer: "> Generated by 🌈 {workflow_name}, see [workflow run]({run_url}). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md)."
+    run-started: "{workflow_name} is processing {event_type}, see [workflow run]({run_url})..."
+    run-success: "✓ {workflow_name} completed successfully, see [workflow run]({run_url})."
+    run-failure: "✗ {workflow_name} encountered {status}, see [workflow run]({run_url})."
   add-comment:
     max: 10
     target: "*"
     hide-older-comments: true
-  # create-pull-request:
-  #   draft: true
-  #   title-prefix: "[Repo Assist] "
-  #   labels: [automation, repo-assist]
-  #   protected-files: fallback-to-issue
-  #   max: 4
-  # push-to-pull-request-branch:
-  #   target: "*"
-  #   title-prefix: "[Repo Assist] "
-  #   max: 4
+  create-pull-request:
+    title-prefix: "Add regression test: "
+    labels: [NO_RELEASE_NOTES, AI-Issue-Regression-PR]
+    reviewers: [abonie, T-Gro]
+    auto-merge: true
+    draft: false
+    allowed-files: ["tests/**", "vsintegration/tests/**"]
+    max: 10
+  push-to-pull-request-branch:
+    target: "*"
+    title-prefix: "[Repo Assist] "
+    max: 4
+    protected-files: fallback-to-issue
   create-issue:
     title-prefix: "[Repo Assist] "
     labels: [automation, repo-assist]
@@ -56,20 +76,106 @@ safe-outputs:
   add-labels:
     allowed: ["AI-thinks-issue-fixed", "AI-thinks-windows-only"]
     max: 30
-    target: "*" 
-  # remove-labels:
-  #   allowed: [bug, enhancement, "help wanted", "good first issue", "spam", "off topic", documentation, question, duplicate, wontfix, "needs triage", "needs investigation", "breaking change", performance, security, refactor]
-  #   max: 5
-  #   target: "*" 
-
-tools:
-  web-fetch:
-  github:
-    toolsets: [all]
-  bash: true
-  repo-memory: true
+    target: "*"
+  remove-labels:
+    allowed: ["AI-thinks-issue-fixed", "AI-thinks-windows-only"]
+    max: 10
+    target: "*"
 
-source: githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02
+steps:
+  - name: Fetch repo data for task weighting
+    env:
+      GH_TOKEN: ${{ github.token }}
+    run: |
+      mkdir -p /tmp/gh-aw
+
+      # Fetch open issues with labels (up to 500)
+      gh issue list --state open --limit 500 --json number,labels > /tmp/gh-aw/issues.json
+
+      # Fetch open PRs with titles (up to 200)
+      gh pr list --state open --limit 200 --json number,title > /tmp/gh-aw/prs.json
+
+      # Compute task weights and select two tasks for this run
+      python3 - << 'EOF'
+      import json, random, os
+
+      with open('/tmp/gh-aw/issues.json') as f:
+          issues = json.load(f)
+      with open('/tmp/gh-aw/prs.json') as f:
+          prs = json.load(f)
+
+      open_issues     = len(issues)
+      unlabelled      = sum(1 for i in issues if not i.get('labels'))
+      repo_assist_prs = sum(1 for p in prs if p['title'].startswith('[Repo Assist]'))
+      other_prs       = sum(1 for p in prs if not p['title'].startswith('[Repo Assist]'))
+
+      task_names = {
+          1:  'Issue Labelling',
+          2:  'Issue Investigation and Comment',
+          3:  'Issue Investigation and Fix',
+          4:  'Engineering Investments',
+          5:  'Coding Improvements',
+          6:  'Maintain Repo Assist PRs',
+          7:  'Stale PR Nudges',
+          8:  'Performance Improvements',
+          9:  'Testing Improvements',
+          10: 'Take the Repository Forward',
+      }
+
+      weights = {
+          1:  1   + 3 * unlabelled,
+          2:  3   + 1 * open_issues,
+          3:  3   + 0.7 * open_issues,
+          4:  5   + 0.2 * open_issues,
+          5:  5   + 0.1 * open_issues,
+          6:  float(repo_assist_prs),
+          7:  0.1 * other_prs,
+          8:  3   + 0.05 * open_issues,
+          9:  3   + 0.05 * open_issues,
+          10: 3   + 0.05 * open_issues,
+      }
+
+      # Seed with run ID for reproducibility within a run
+      run_id = int(os.environ.get('GITHUB_RUN_ID', '0'))
+      rng = random.Random(run_id)
+
+      task_ids     = list(weights.keys())
+      task_weights = [weights[t] for t in task_ids]
+
+      # Weighted sample without replacement (pick 2 distinct tasks)
+      chosen, seen = [], set()
+      for t in rng.choices(task_ids, weights=task_weights, k=30):
+          if t not in seen:
+              seen.add(t)
+              chosen.append(t)
+          if len(chosen) == 2:
+              break
+
+      print('=== Repo Assist Task Selection ===')
+      print(f'Open issues       : {open_issues}')
+      print(f'Unlabelled issues : {unlabelled}')
+      print(f'Repo Assist PRs   : {repo_assist_prs}')
+      print(f'Other open PRs    : {other_prs}')
+      print()
+      print('Task weights:')
+      for t, w in weights.items():
+          tag = ' <-- SELECTED' if t in chosen else ''
+          print(f'  Task {t:2d} ({task_names[t]}): weight {w:6.1f}{tag}')
+      print()
+      print(f'Selected tasks for this run: Task {chosen[0]} ({task_names[chosen[0]]}) and Task {chosen[1]} ({task_names[chosen[1]]})')
+
+      result = {
+          'open_issues': open_issues, 'unlabelled_issues': unlabelled,
+          'repo_assist_prs': repo_assist_prs, 'other_prs': other_prs,
+          'task_names': task_names,
+          'weights': {str(k): round(v, 2) for k, v in weights.items()},
+          'selected_tasks': chosen,
+      }
+      with open('/tmp/gh-aw/task_selection.json', 'w') as f:
+          json.dump(result, f, indent=2)
+      EOF
+
+source: githubnext/agentics/workflows/repo-assist.md@7c7feb61a52b662eb2089aa2945588b7a200d404
 ---
 
 # Repo Assist
@@ -78,7 +184,7 @@ source: githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa96662
 
 Take heed of **instructions**: "${{ steps.sanitized.outputs.text }}"
 
-If these are non-empty (not ""), then you have been triggered via `/repo-assist <instructions>`. Follow the user's instructions instead of the normal scheduled workflow. Focus exclusively on those instructions. Apply all the same guidelines (read AGENTS.md, run formatters/linters/tests, be polite, use AI disclosure). Skip the weighted task selection and Task 11 reporting, and instead directly do what the user requested. If no specific instructions were provided (empty or blank), proceed with the normal scheduled workflow below.
+If these are non-empty (not ""), then you have been triggered via `/repo-assist <instructions>`. Follow the user's instructions instead of the normal scheduled workflow. Focus exclusively on those instructions. Apply all the same guidelines (read AGENTS.md, run formatters/linters/tests, be polite, use AI disclosure). Skip the normal task sequence and the monthly activity summary update, and instead directly do what the user requested. If no specific instructions were provided (empty or blank), proceed with the normal scheduled workflow below.
 
 Then exit  -  do not run the normal workflow after completing the instructions.
 
@@ -92,33 +198,58 @@ Always be:
 - **Concise**: Keep comments focused and actionable. Avoid walls of text.
 - **Mindful of project values**: Prioritize **stability**, **correctness**, and **minimal dependencies**. Do not introduce new dependencies without clear justification.
 - **Transparent about your nature**: Always clearly identify yourself as Repo Assist, an automated AI assistant. Never pretend to be a human maintainer.
-- **Restrained**: When in doubt, do nothing. It is always better to stay silent than to post a redundant, unhelpful, or spammy comment. Human maintainers' attention is precious  -  do not waste it.
+- **Restrained**: When in doubt and lacking verified evidence, do nothing. It is always better to stay silent than to post a redundant, unhelpful, or spammy comment. Human maintainers' attention is precious  -  do not waste it.
 
 ## Memory
 
-Use persistent repo memory to track:
+Use persistent repo memory to track. The memory is stored in `state.json` on the `memory/repo-assist` branch.
+
+The current schema uses these fields (extend as needed, but never remove existing fields):
 
-- issues already commented on (with timestamps to detect new human activity)
-- fix attempts and outcomes, improvement ideas already submitted, a short to-do list
-- a **backlog cursor** so each run continues where the previous one left off
-- a second **backlog windows-only cursor** for addressing issues that were given up too easily and labelled "AI-thinks-windows-only" too eagerly
-- previously checked off items (checked off by maintainer) in the Monthly Activity Summary to maintain an accurate pending actions list for maintainers
-- very concise tips and tricks for reproducing issues
+```json
+{
+  "c": 12067,                 // backlog cursor — last processed issue number (ascending order)
+  "lr": "2026-03-26",        // last run date — ISO date string
+  "ms": 19439,               // monthly summary issue number
+  "woc": 5858,               // windows-only revisit cursor — last processed issue number
+  "rtc": 6648                // regression test cursor — last processed issue number
+}
+```
+
+Guidelines for memory evolution:
+- Add new fields with short keys (2-3 chars) to keep the JSON compact
+- Use issue numbers for cursors (resume from issues with number > cursor value)
+- Do NOT track "issues commented on" in memory — instead, check the issue's comments directly to see if Repo Assist already commented. This is authoritative and doesn't grow unboundedly.
+- The existing `cm` field is deprecated. Ignore it if present; do not add to it.
 
 Read memory at the **start** of every run; update it at the **end**.
 
 **Important**: Memory may not be 100% accurate. Issues may have been created, closed, or commented on; PRs may have been created, merged, commented on, or closed since the last run. Always verify memory against current repository state — reviewing recent activity since your last run is wise before acting on stale assumptions.
 
-**Memory backlog tracking**: Your memory may contain notes about issues or PRs that still need attention (e.g., "issues #384, #336 have labels but no comments"). These are **action items for you**, not just informational notes. Each run, check your memory's `notes` field and other tracking fields for any explicitly flagged backlog work, and prioritise acting on it.
+**Memory backlog tracking**: Before commenting on any issue, check the issue's existing comments for a Repo Assist comment (look for the `🤖` marker). To detect new human activity, compare the latest human comment timestamp against `lr`. Only re-engage if new human comments appeared after `lr`.
+
+## Working with Issues — Mandatory Rules
+
+Before taking ANY action on an issue (commenting, labeling, creating a PR), you **must** read the FULL comment history — not just the issue body. This is non-negotiable.
+
+1. **Read ALL comments, in order, noting timestamps and authors.** Pay special attention to human comments that appeared AFTER a previous Repo Assist comment — these may dispute, correct, or supersede the bot's analysis.
+
+2. **Never ignore human feedback.** If a human replied to a Repo Assist comment saying "this is wrong" or "still broken", your next action must acknowledge and address their feedback. Posting a test that ignores a human correction is worse than doing nothing.
+
+3. **Never loop with yourself.** If the last comment on an issue is from Repo Assist and no human has responded, do NOT post another comment. Wait for human engagement. Also, before posting, check if your new comment would convey the same information as your previous comment — if so, skip it.
+
+4. **Use the best available repros.** Comments often contain simplified, corrected, or additional repro steps. Use the most recent and most precise repro, not just the original issue body. If multiple distinct repro scenarios exist (e.g., issue body shows one case, a commenter shows a different triggering pattern), include all of them — each becomes a separate test case in the regression test.
+
+5. **If a human disputed a previous bot claim**, treat the issue as if the bot never commented. Start fresh — verify independently, and explicitly acknowledge the human's point in your new comment.
 
 ## Workflow
 
-Each run, do Task 1 and Task FINAL
+Each run, do Task 1, Task 3, Task 2, and Task FINAL (in this order — Task 3 feeds into Task 2)
 
 ### Task 1: Issue Investigation and Comment
 
-1. List open issues sorted by creation date ascending (oldest first). Resume from your memory's backlog cursor; reset when you reach the end. **Do not assess issues posted after 1/1/2023** to avoid noise from more recent issues that haven't had time for human engagement yet.
-2. **Work through "Bug" issues in reverse order, from the oldest open issue.** Read the issue comments and check memory's `comments_made` field. For every issue previously labeled as "AI-thinks-windows-only", do revisit it again and reassess.
+1. List open issues sorted by creation date ascending (oldest first). Resume from issues with number > the `c` cursor. **Do not assess issues posted after 1/1/2024** to avoid noise from more recent issues that haven't had time for human engagement yet. When no more issues exist above `c` within the cutoff date, reset `c` to 0 at the end of this run — on the next run, the `lr`-based activity filter will prevent re-investigating stale issues.
+2. **Work through "Bug" issues in ascending order, starting from the oldest open issue.** Read the issue comments and check if Repo Assist has already commented (look for the `🤖` marker). When the cursor has reset and you're re-scanning previously visited issues, **skip issues that have no activity (no new comments) since `lr`** — they haven't changed since you last saw them.
 3. We want automatic analysis to focus on BUGS trying to identify issues that are fixed or issues that even after numerous rounds of trying hard are determined to be investigable Windows-only and labelling them.
 - You shall verify with fresh version of the compiler, library and tooling by following the ./build.sh script at repo root. You can build this at the start of your session, and use the same artifacts for many issues. Running tests, or even launching fsi.exe from the artifacts folder for quick repro.
 - Do not guess, verify. Do not ask "maintainer to verify", you verify and give high-confidence proofs about whatever you found out:
@@ -127,18 +258,164 @@ Each run, do Task 1 and Task FINAL
   - any other findings. If the issue remains but you have some insight, write it down!
   - Never write "for maintainers to verify", this helps absolutely nobody. You verify, you have the tools.
 - For issues that are honestly asssessed to be fixed via solid reproduction steps, the label "AI-thinks-issue-fixed" should be applied and a response giving reasoning and repro if available
-- For issues assess to be Windows only, the label "AI-thinks-windows-only" should be applied and no reasoning given and no comment added. However, do not be eagerly dismissive. Have a look at FSharp.Compiler.Service.Tests - the public API (consumed by VS, true) is OS agnostic. Features like autocomplete, find references, even debugging (via .pdb files) or various VS shown diagnostics - are available without visual studio. Also tooltips and parts of navigation.
-- Otherwise, do nothing to avoid noise. If you don't have high confidence in a fix or in the Windows-only nature of the issue, it's better to say nothing than to risk a false positive comment or label. If you have some other high-confidence judgement about the issue, you can leave a note to the maintainer in the "Additional observations" section of the Monthly Activity Summary issue, but do not comment directly on the issue itself. If you have written solid reproduction not yet covered in the issue, write it down even if the issue still remains. This will help future implementers as an easily approachable repro case.
-4. Expect to engage substantively on 1–10 issues per run; you may scan many more to find good candidates. 
+- **Windows-only labelling — STRICT RULES.** Do NOT label an issue `AI-thinks-windows-only` unless you have verified it is truly untestable outside Visual Studio. The following are **NOT windows-only** — they are backed by FSharp.Compiler.Service and testable on any OS:
+    - Semantic highlighting / classification / colorization → FCS `Tokenizer`, `Classifier` APIs
+    - Tooltips / QuickInfo → FCS `GetToolTip` / `GetStructuredToolTipText`
+    - Find all references → FCS `GetUsesOfSymbolInFile`
+    - Rename symbol → FCS rename logic (even if reported via VS rename UI)
+    - Autocomplete / IntelliSense → FCS `GetDeclarationListInfo`
+    - Diagnostics display / error squiggles → FCS type checking
+    - Code fixes and refactorings → testable via FCS APIs
+    - Signature generation → FCS `GetSignatureText`
+    - Navigation / Go to definition → FCS symbol resolution
+    - Debugging / breakpoints / sequence points → PDB generation, testable via IL verification
+
+  The ONLY issues that are truly windows-only are those involving:
+    - VS-specific UI rendering (WPF controls, editor chrome, scroll bars, sticky scroll visual behavior)
+    - VS project system integration (solution explorer, project properties dialog)
+    - VS-specific installation / VSIX / extension loading
+    - VS-specific keyboard shortcuts or editor commands with no FCS equivalent
+    - Cross-process VS interaction (e.g., FSI output pane rendering in VS)
+
+  If you previously labelled issues as windows-only that fall into the testable category above, you were wrong. Task 3 below will systematically revisit and correct those.
+
+- Otherwise, do nothing to avoid noise. If you don't have high confidence in a fix, it's better to say nothing than to risk a false positive. If you have some other high-confidence judgement, leave a note in the "Additional observations" section of the Monthly Activity Summary. If you have written a solid reproduction not yet covered in the issue, write it down — this helps future implementers.
+4. Expect to engage substantively on 1–10 issues per run; you may scan many more to find good candidates. **After each issue where you comment or label, call the safe output tool immediately** — do not defer outputs.
 5. Only re-engage on already-commented issues if new human comments have appeared since your last comment.
 6. Begin every comment with: `🤖 *This is an automated response from Repo Assist.*`
 7. Update memory with comments made and the new cursor position - and also the second cursor for "windows-only" reassessment.
 
+### Task 2: Regression Test Verification (for every AI-thinks-issue-fixed claim)
+
+After Task 1 and Task 3, process every open issue that carries the `AI-thinks-issue-fixed` label (including issues that received the label during Task 1 or Task 3 in this run). For each such issue, you must produce **exactly one** of the three outcomes below. No issue may be left with the label and no verification outcome.
+
+#### Step A — Check for existing test coverage and PRs
+
+First, check if this issue has already been handled. Skip to the next issue if ANY of these are true:
+1. The issue is **closed** — someone already resolved it
+2. A regression test PR exists (open or merged): `gh pr list --repo dotnet/fsharp --label "AI-Issue-Regression-PR" --search "{issue_number}" --state all`
+3. The issue body or comments link to a PR that addresses it
+4. Repo Assist already posted a test-link comment (a comment containing a GitHub permalink to a test file)
+5. Repo Assist already posted an "untestable" explanation (Outcome 3 from a previous run)
+6. A human already posted a comment with test coverage or a fix reference after the `AI-thinks-issue-fixed` label was applied
+
+**Creating a duplicate PR or duplicate comment is a reputation-damaging mistake.**
+
+Then search the test suite (`tests/`) thoroughly for existing test coverage:
+
+1. **Easy**: `grep -r "12345\|#12345" tests/` (substituting the actual issue number) — does any test mention the issue number?
+2. **Medium**: Search for the repro pattern from the issue. The test may be named differently, simplified, or part of a broader test.
+3. **Hard**: Search for semantically similar setups — same language construct, same error code, same compiler area — even if naming is completely different.
+
+#### Step B — Dispute verification (mandatory for every candidate match)
+
+For every candidate test you find, you **must** reason adversarially before accepting it. Adopt the following stance and work through it explicitly:
+
+> "Attempt to REJECT the claim that test `{test name}` in `{file path}` adequately covers issue #{number} ({issue title}). Check: (1) Does the test SETUP reproduce the exact scenario described in the issue? (2) Do the ASSERTIONS verify the exact behavior the issue reports as broken/fixed? Both must match. If either the setup or the assertions fail to cover what the issue describes, explain precisely what is missing. Look for gaps, not confirmations."
+
+Only if this adversarial analysis **fails to find gaps** (i.e., confirms the test really does cover the issue) may you use Outcome 1 below.
+
+#### Step C — Outcomes (exactly one per issue)
+
+**Outcome 1: Existing test covers the issue.**
+
+Comment on the issue with:
+- A permalink to the test source on GitHub (e.g., `https://github.com/dotnet/fsharp/blob/{commit_sha}/tests/path/File.fs#L10-L25`). GitHub automatically renders this as an embedded code snippet. Use the current HEAD commit SHA, not a branch name, so the link is permanent.
+- A one-sentence explanation of why this test covers the issue
+
+**Outcome 2: Write a new regression test and raise a PR.**
+
+This is the primary expected outcome when no existing test is found.
+
+1. **Choose the right location.** Place the test in the semantically appropriate project, folder, and file based on the compiler feature area. **You may ONLY add or modify files under `tests/` or `vsintegration/tests/`. Never modify files under `src/`** — regression test PRs verify existing fixes, they do not implement fixes:
+   - Type checking / diagnostics → `tests/FSharp.Compiler.ComponentTests/ErrorMessages/` or the relevant `Conformance/` subfolder
+   - Code generation / IL → `tests/FSharp.Compiler.ComponentTests/EmittedIL/`
+   - Optimizer → `tests/FSharp.Compiler.ComponentTests/Optimize/`
+   - Language service (completions, tooltips, find references) → `tests/FSharp.Compiler.Service.Tests/` — **most IDE issues ARE testable on Linux** since the FSharp.Compiler.Service layer is OS-agnostic
+   - FSI → `tests/FSharp.Compiler.ComponentTests/Scripting/`
+   - Parser / syntax → `tests/FSharp.Compiler.ComponentTests/Language/` or `Conformance/`
+
+2. **Write the test** using the repro from the issue body AND comments (per "Working with Issues" rules — use the best available repro, which may be in a comment, not the original body). Follow the ComponentTests DSL pipeline pattern:
+   ```fsharp
+   // https://github.com/dotnet/fsharp/issues/{number}
+   [<Fact>]
+   let ``Issue {number} - brief description`` () =
+       FSharp """
+   // minimal repro from issue
+       """
+       |> typecheck  // or compile, compileExeAndRun as appropriate
+       |> shouldSucceed
+   ```
+
+3. **Build and run the test** to confirm it passes. **Limit yourself to at most 3 build-and-test cycles per issue** — if the test still doesn't pass after 3 attempts, the issue is likely not fixed (go to step 5). Do not create multiple test file variants; iterate on a single test file:
+   ```bash
+   dotnet build tests/{TestProject}/{TestProject}.fsproj -c Release
+   dotnet test tests/{TestProject}/{TestProject}.fsproj -c Release --no-build -- --filter-method "*Issue {number}*"
+   ```
+
+4. **If the test PASSES**: Before creating a PR, run the duplicate check from Step A one more time (another run may have created a PR since you last checked). Then create the PR **immediately** (do not defer to the end of the run):
+   - Branch: `regression-test/issue{number}`
+   - Title: `Add regression test: #{number}, {brief description}`
+   - Body: **Must** contain `Fixes https://github.com/dotnet/fsharp/issues/{number}` on its own line — this is non-negotiable. GitHub automatically closes the issue when the PR is merged. This is the ONLY mechanism for closing issues. The workflow must never close issues directly.
+   - Labels: `NO_RELEASE_NOTES`, `AI-Issue-Regression-PR`
+   - Reviewers: `abonie`, `T-Gro`
+   - Auto-merge: squash
+   - If the .fsproj needs a new `<Compile Include=.../>` entry, add it in alphabetical order within its section
+
+5. **If the test FAILS** (including after exhausting the 3-attempt limit): The issue is **not fixed**. Do all of the following **immediately** (do not defer):
+   - **Remove** the `AI-thinks-issue-fixed` label from the issue
+   - **Comment** on the issue with the test code, the failure output, and the conclusion that the issue remains open
+   - Do **not** create a PR
+
+**Outcome 3: Issue is genuinely untestable (expect <1% of cases).**
+
+Some issues cannot be verified with a test (e.g., documentation changes, IDE-specific UI rendering, installer issues). In this case:
+
+- Comment on the issue with a **precise, thorough explanation** of why no automated test can cover this specific issue
+- Provide alternative proof of the fix (e.g., link to the commit that fixed it, screenshots, or manual verification steps you performed)
+- This outcome is rare. If in doubt, the issue IS testable — IDE features like completions, tooltips, find references, diagnostics display, and navigation all work through FSharp.Compiler.Service and are testable on any OS
+
+#### Step D — Rate limiting and batching
+
+Process up to 5 issues per run. List all issues with the `AI-thinks-issue-fixed` label, ordered by issue number ascending. Skip issues with number ≤ `rtc`. After processing, set `rtc` to the highest issue number processed. Do NOT reset `rtc` to 0 — new issues that receive the label will have higher numbers and be picked up naturally.
+
+### Task 3: Revisit AI-thinks-windows-only Claims
+
+The `AI-thinks-windows-only` label was applied too eagerly in the past. Many issues labelled as windows-only are actually testable via FSharp.Compiler.Service on Linux/macOS. This task systematically revisits those claims.
+
+#### Process
+
+1. List all open issues with the `AI-thinks-windows-only` label, ordered by issue number ascending.
+2. Skip issues with number ≤ `woc` (already processed in previous runs).
+3. Process up to 5 issues from the remaining list.
+4. After processing, set `woc` to the highest issue number you processed. Do NOT reset `woc` to 0 — once all windows-only issues have been revisited, the task naturally has nothing to do until new issues receive the label (which will have higher numbers).
+
+#### Per-issue assessment
+
+For each `AI-thinks-windows-only` issue (process up to 5 per run):
+
+1. **Read the issue carefully.** Understand what the actual bug or feature request is about.
+
+2. **Classify it honestly.** Ask: "Is the underlying behavior implemented in FSharp.Compiler.Service, or is it purely in VS-specific code (`vsintegration/` WPF/UI layer)?"
+
+   - If the feature is in FCS (classification, tooltips, rename, completions, diagnostics, find references, code fixes, navigation, signature help, etc.) → **it is NOT windows-only**. Remove the `AI-thinks-windows-only` label, then:
+     1. Build the compiler and attempt to reproduce the issue on Linux using the repro from the issue (and comments — see "Working with Issues" rules above)
+     2. If the issue **still reproduces**: leave a comment with your repro and findings. Do not apply any "fixed" label.
+     3. If the issue **no longer reproduces**: apply `AI-thinks-issue-fixed` and add this issue to the Task 2 queue for the current run. Task 2 will then search for existing tests, run adversarial verification, and either point to an existing test or create a regression test PR.
+
+   - If the feature is purely VS chrome (WPF rendering, project system dialogs, VSIX loading, VS-specific key bindings, FSI output pane visual rendering) → the label is correct. Leave it.
+
+3. **When removing the label**, comment on the issue explaining that the issue's underlying feature (name it: classification, rename, tooltips, etc.) is testable via FSharp.Compiler.Service and is not windows-only. Then proceed to investigate the issue normally.
+
+#### Goal
+
+Over successive runs, every `AI-thinks-windows-only` issue will be revisited. Issues that were mislabelled get the label removed and are investigated properly. Issues that are genuinely windows-only keep the label. The end state is a clean, trustworthy set of labels.
+
 ### Task FINAL: Update Monthly Activity Summary Issue (ALWAYS DO THIS TASK IN ADDITION TO OTHERS)
 
 Maintain a single open issue titled `[Repo Assist] Monthly Activity {YYYY}-{MM}` as a rolling summary of all Repo Assist activity for the current month.
 
-1. Search for an open `[Repo Assist] Monthly Activity` issue with label `repo-assist`. If it's for the current month, update it. If for a previous month, close it and create a new one. Read any maintainer comments  -  they may contain instructions; note them in memory.
+1. Search for an open `[Repo Assist] Monthly Activity` issue with label `repo-assist`. If it's for the current month, update it. If for a previous month, leave it — a maintainer will close it — and create a new one for the current month. Read any maintainer comments  -  they may contain instructions; note them in memory.
 2. **Issue body format**  -  use **exactly** this structure:
 
    ```markdown
@@ -148,7 +425,7 @@ Maintain a single open issue titled `[Repo Assist] Monthly Activity {YYYY}-{MM}`
 
    ## Suggested Actions for Maintainer
 
-   **Comprehensive list** of all pending actions requiring maintainer attention (excludes items already actioned and checked off). 
+   **Comprehensive list** of all pending actions requiring maintainer attention (excludes items already actioned and checked off).
    - Reread the issue you're updating before you update it  -  there may be new checkbox adjustments since your last update that require you to adjust the suggested actions.
    - List **all** the comments, PRs, and issues that need attention
    - Exclude **all** items that have either
@@ -161,14 +438,12 @@ Maintain a single open issue titled `[Repo Assist] Monthly Activity {YYYY}-{MM}`
    * [ ] **Review PR** #<number>: <summary>  -  [Review](<link>)
    * [ ] **Check comment** #<number>: Repo Assist commented  -  verify guidance is helpful  -  [View](<link>)
    * [ ] **Merge PR** #<number>: <reason>  -  [Review](<link>)
-   * [ ] **Close issue** #<number>: <reason>  -  [View](<link>)
-   * [ ] **Close PR** #<number>: <reason>  -  [View](<link>)
    * [ ] **Define goal**: <suggestion>  -  [Related issue](<link>)
 
    *(If no actions needed, state "No suggested actions at this time.")*
-   
+
    ## Additional observations for maintainer's attention
-   
+
    Sometimes when analyzing isssues, you won't have been able to determine a clear action item, but you may have discovered with high confidence that the issue has an easy fix, or should be closed, or is a duplicate, or some other simple action. If so, leave a once sentence note for the maintainer here -  e.g. "Issue #384 looks like it has an easy fix because ...". If you have a repro not yet covered in issue details, but proves the issue and is easily repeatable - write it down.
 
    ## Future Work for Repo Assist
@@ -209,7 +484,19 @@ Maintain a single open issue titled `[Repo Assist] Monthly Activity {YYYY}-{MM}`
 ## Guidelines
 
 - **AI transparency**: every comment, PR, and issue must include a Repo Assist disclosure with 🤖.
-- **Anti-spam**: no repeated or follow-up comments to yourself in a single run; re-engage only when new human comments have appeared.
+- **Anti-spam**: no redundant or repeated comments to yourself in a single run. Different tasks (investigation vs. test verification) posting on the same issue in the same run is acceptable when each comment serves a distinct purpose.
 - **Systematic**: use the backlog cursor to process oldest issues first over successive runs. Do not stop early.
 - **Quality over quantity**: noise erodes trust. Do nothing rather than add low-value output.
-- **Bias toward action**: While avoiding spam, actively seek ways to contribute value within the two selected tasks. A "no action" run should be genuinely exceptional.
+- **Bias toward action**: While avoiding spam, actively seek ways to contribute value within each task. A "no action" run should be genuinely exceptional. The threshold for commenting is: you have verified evidence (reproduction, test results, or commit references) to support your statement, and that evidence is not apparent from or duplicate with the existing description or comments.
+
+## Safe Output Discipline
+
+Every run **must** produce at least one safe output call. Follow these rules:
+
+1. **Produce outputs incrementally.** After completing work on each issue (commenting, labeling, creating a PR), call the safe output tool **immediately** — do not batch all outputs until the end of the run. This ensures partial work is captured even if the run is interrupted or you exhaust your context window.
+
+2. **Call `noop` if no action is warranted.** If after completing all tasks you have genuinely nothing to output (no comments, no labels, no PRs, no monthly summary update), call the `noop` tool with a brief explanation (e.g., "All scanned issues already have Repo Assist comments and no new activity since last run"). A run that produces zero safe outputs is treated as a failure by the workflow infrastructure.
+
+3. **Limit iteration on any single issue.** When writing a regression test (Task 2), allow at most **3 build-and-test cycles** per issue. If the test still fails after 3 attempts, conclude that the issue is not fixed: remove the `AI-thinks-issue-fixed` label, comment with your findings and the failing test code, and move on. Do not spend unbounded time iterating on a single test.
+
+4. **Time awareness.** You have a 60-minute timeout. Reserve at least 10 minutes for Task FINAL (monthly summary update). If you are deep in Task 2 test creation and have used over 40 minutes, wrap up the current issue and proceed to Task FINAL.
diff --git a/NuGet.config b/NuGet.config
index 527f95b5c87..ce7fe711793 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -8,6 +8,7 @@
     <clear />
     <!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
     <!--  Begin: Package sources from DotNet-msbuild-Trusted -->
+    <add key="darc-pub-DotNet-msbuild-Trusted-e5ebe15" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-DotNet-msbuild-Trusted-e5ebe156/nuget/v3/index.json" />
     <!--  End: Package sources from DotNet-msbuild-Trusted -->
     <!--End: Package sources managed by Dependency Flow automation. Do not edit the sources above.-->
     <add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
index a3be66419ad..d2d59c319a1 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
@@ -1,5 +1,10 @@
 ### Fixed
 
+* Fix DU case names matching IWSAM member names no longer cause duplicate property entries. (Issue [#14321](https://github.com/dotnet/fsharp/issues/14321), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
+* Fix DefaultAugmentation(false) duplicate entry in method table. (Issue [#16565](https://github.com/dotnet/fsharp/issues/16565), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
+* Fix abstract event accessors now have SpecialName flag. (Issue [#5834](https://github.com/dotnet/fsharp/issues/5834), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
+* Fix warning 20 ("expression is implicitly ignored") pointing at the wrong range when the last expression in a sequential block (e.g. inside `for`, `while` loops) is non-unit. The squiggle now correctly highlights only the offending expression. ([Issue #5735](https://github.com/dotnet/fsharp/issues/5735), [PR #19504](https://github.com/dotnet/fsharp/pull/19504))
+* Fix CLIEvent properties to be correctly recognized as events: `IsEvent` returns `true` and `XmlDocSig` uses `E:` prefix instead of `P:`. ([Issue #10273](https://github.com/dotnet/fsharp/issues/10273), [PR #18584](https://github.com/dotnet/fsharp/pull/18584))
 * Fix extra sequence point at the end of match expressions. ([Issue #12052](https://github.com/dotnet/fsharp/issues/12052), [PR #19278](https://github.com/dotnet/fsharp/pull/19278))
 * Fix wrong sequence point range for `return`/`yield`/`return!`/`yield!` inside computation expressions. ([Issue #19248](https://github.com/dotnet/fsharp/issues/19248), [PR #19278](https://github.com/dotnet/fsharp/pull/19278))
 * Fix extra out-of-order sequence point for `use` in `task` computation expressions. ([Issue #19255](https://github.com/dotnet/fsharp/issues/19255), [PR #19278](https://github.com/dotnet/fsharp/pull/19278))
@@ -13,6 +18,7 @@
 * Fix `YieldFromFinal`/`ReturnFromFinal` being incorrectly called in non-tail positions (`for`, `use`, `use!`, `try/with` handler). ([Issue #19402](https://github.com/dotnet/fsharp/issues/19402), [PR #19403](https://github.com/dotnet/fsharp/pull/19403))
 * Fixed how the source ranges of warn directives are reported (as trivia) in the parser output (by not reporting leading spaces). ([Issue #19405](https://github.com/dotnet/fsharp/issues/19405), [PR #19408]((https://github.com/dotnet/fsharp/pull/19408)))
 * Fix UoM value type `ToString()` returning garbage values when `--checknulls+` is enabled, caused by double address-taking in codegen. ([Issue #19435](https://github.com/dotnet/fsharp/issues/19435), [PR #19440](https://github.com/dotnet/fsharp/pull/19440))
+* Fix completion inconsistently showing some obsolete members (fields and events) while hiding others (methods and properties). All obsolete members are now consistently hidden by default. ([Issue #13512](https://github.com/dotnet/fsharp/issues/13512), [PR #19506](https://github.com/dotnet/fsharp/pull/19506))
 
 ### Added
 
diff --git a/eng/Version.Details.props b/eng/Version.Details.props
index 21810fac23e..6a4a344f724 100644
--- a/eng/Version.Details.props
+++ b/eng/Version.Details.props
@@ -6,27 +6,27 @@ This file should be imported by eng/Versions.props
 <Project>
   <PropertyGroup>
     <!-- dotnet-arcade dependencies -->
-    <MicrosoftDotNetArcadeSdkPackageVersion>10.0.0-beta.26168.1</MicrosoftDotNetArcadeSdkPackageVersion>
+    <MicrosoftDotNetArcadeSdkPackageVersion>10.0.0-beta.26208.4</MicrosoftDotNetArcadeSdkPackageVersion>
     <!-- dotnet-msbuild dependencies -->
-    <MicrosoftBuildPackageVersion>18.6.0-preview-26173-02</MicrosoftBuildPackageVersion>
-    <MicrosoftBuildFrameworkPackageVersion>18.6.0-preview-26173-02</MicrosoftBuildFrameworkPackageVersion>
-    <MicrosoftBuildTasksCorePackageVersion>18.6.0-preview-26173-02</MicrosoftBuildTasksCorePackageVersion>
-    <MicrosoftBuildUtilitiesCorePackageVersion>18.6.0-preview-26173-02</MicrosoftBuildUtilitiesCorePackageVersion>
+    <MicrosoftBuildPackageVersion>18.6.1</MicrosoftBuildPackageVersion>
+    <MicrosoftBuildFrameworkPackageVersion>18.6.1</MicrosoftBuildFrameworkPackageVersion>
+    <MicrosoftBuildTasksCorePackageVersion>18.6.1</MicrosoftBuildTasksCorePackageVersion>
+    <MicrosoftBuildUtilitiesCorePackageVersion>18.6.1</MicrosoftBuildUtilitiesCorePackageVersion>
     <!-- dotnet-optimization dependencies -->
-    <optimizationlinuxarm64MIBCRuntimePackageVersion>1.0.0-prerelease.26153.1</optimizationlinuxarm64MIBCRuntimePackageVersion>
-    <optimizationlinuxx64MIBCRuntimePackageVersion>1.0.0-prerelease.26153.1</optimizationlinuxx64MIBCRuntimePackageVersion>
-    <optimizationwindows_ntarm64MIBCRuntimePackageVersion>1.0.0-prerelease.26153.1</optimizationwindows_ntarm64MIBCRuntimePackageVersion>
-    <optimizationwindows_ntx64MIBCRuntimePackageVersion>1.0.0-prerelease.26153.1</optimizationwindows_ntx64MIBCRuntimePackageVersion>
-    <optimizationwindows_ntx86MIBCRuntimePackageVersion>1.0.0-prerelease.26153.1</optimizationwindows_ntx86MIBCRuntimePackageVersion>
+    <optimizationlinuxarm64MIBCRuntimePackageVersion>1.0.0-prerelease.26180.1</optimizationlinuxarm64MIBCRuntimePackageVersion>
+    <optimizationlinuxx64MIBCRuntimePackageVersion>1.0.0-prerelease.26180.1</optimizationlinuxx64MIBCRuntimePackageVersion>
+    <optimizationwindows_ntarm64MIBCRuntimePackageVersion>1.0.0-prerelease.26180.1</optimizationwindows_ntarm64MIBCRuntimePackageVersion>
+    <optimizationwindows_ntx64MIBCRuntimePackageVersion>1.0.0-prerelease.26180.1</optimizationwindows_ntx64MIBCRuntimePackageVersion>
+    <optimizationwindows_ntx86MIBCRuntimePackageVersion>1.0.0-prerelease.26180.1</optimizationwindows_ntx86MIBCRuntimePackageVersion>
     <!-- dotnet-roslyn dependencies -->
-    <MicrosoftCodeAnalysisPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisPackageVersion>
-    <MicrosoftCodeAnalysisCompilersPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisCompilersPackageVersion>
-    <MicrosoftCodeAnalysisCSharpPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisCSharpPackageVersion>
-    <MicrosoftCodeAnalysisEditorFeaturesPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisEditorFeaturesPackageVersion>
-    <MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>
-    <MicrosoftCodeAnalysisExternalAccessFSharpPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisExternalAccessFSharpPackageVersion>
-    <MicrosoftCodeAnalysisFeaturesPackageVersion>5.6.0-2.26173.11</MicrosoftCodeAnalysisFeaturesPackageVersion>
-    <MicrosoftVisualStudioLanguageServicesPackageVersion>5.6.0-2.26173.11</MicrosoftVisualStudioLanguageServicesPackageVersion>
+    <MicrosoftCodeAnalysisPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisPackageVersion>
+    <MicrosoftCodeAnalysisCompilersPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisCompilersPackageVersion>
+    <MicrosoftCodeAnalysisCSharpPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisCSharpPackageVersion>
+    <MicrosoftCodeAnalysisEditorFeaturesPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisEditorFeaturesPackageVersion>
+    <MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>
+    <MicrosoftCodeAnalysisExternalAccessFSharpPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisExternalAccessFSharpPackageVersion>
+    <MicrosoftCodeAnalysisFeaturesPackageVersion>5.7.0-1.26209.5</MicrosoftCodeAnalysisFeaturesPackageVersion>
+    <MicrosoftVisualStudioLanguageServicesPackageVersion>5.7.0-1.26209.5</MicrosoftVisualStudioLanguageServicesPackageVersion>
     <!-- dotnet-runtime dependencies -->
     <SystemCollectionsImmutablePackageVersion>10.0.2</SystemCollectionsImmutablePackageVersion>
     <SystemCompositionPackageVersion>10.0.2</SystemCompositionPackageVersion>
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index f9870afccc9..624ac68b330 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,54 +1,54 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Dependencies>
-  <Source Uri="https://github.com/dotnet/dotnet" Mapping="fsharp" Sha="542fea6988c173c64859bab06c9d2d100034843c" BarId="305563" />
+  <Source Uri="https://github.com/dotnet/dotnet" Mapping="fsharp" Sha="1a405c76db678301b6f6f5b22d2a63a152c26b97" BarId="309188" />
   <ProductDependencies>
-    <Dependency Name="Microsoft.Build" Version="18.6.0-preview-26173-02">
+    <Dependency Name="Microsoft.Build" Version="18.6.1">
       <Uri>https://github.com/dotnet/msbuild</Uri>
-      <Sha>6c499a72be37b21dbc32e8b03685aeec3092f599</Sha>
+      <Sha>e5ebe15655a6be2b2e3209464d0cde1b8825ab57</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.Build.Framework" Version="18.6.0-preview-26173-02">
+    <Dependency Name="Microsoft.Build.Framework" Version="18.6.1">
       <Uri>https://github.com/dotnet/msbuild</Uri>
-      <Sha>6c499a72be37b21dbc32e8b03685aeec3092f599</Sha>
+      <Sha>e5ebe15655a6be2b2e3209464d0cde1b8825ab57</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.Build.Tasks.Core" Version="18.6.0-preview-26173-02">
+    <Dependency Name="Microsoft.Build.Tasks.Core" Version="18.6.1">
       <Uri>https://github.com/dotnet/msbuild</Uri>
-      <Sha>6c499a72be37b21dbc32e8b03685aeec3092f599</Sha>
+      <Sha>e5ebe15655a6be2b2e3209464d0cde1b8825ab57</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.Build.Utilities.Core" Version="18.6.0-preview-26173-02">
+    <Dependency Name="Microsoft.Build.Utilities.Core" Version="18.6.1">
       <Uri>https://github.com/dotnet/msbuild</Uri>
-      <Sha>6c499a72be37b21dbc32e8b03685aeec3092f599</Sha>
+      <Sha>e5ebe15655a6be2b2e3209464d0cde1b8825ab57</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis.Features" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis.Features" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis.EditorFeatures" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis.EditorFeatures" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis.ExternalAccess.FSharp" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis.ExternalAccess.FSharp" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.CodeAnalysis.Compilers" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.CodeAnalysis.Compilers" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.VisualStudio.LanguageServices" Version="5.6.0-2.26173.11">
+    <Dependency Name="Microsoft.VisualStudio.LanguageServices" Version="5.7.0-1.26209.5">
       <Uri>https://github.com/dotnet/roslyn</Uri>
-      <Sha>bd2083ff6d56b296fa1ea5647850c166b5e55fb7</Sha>
+      <Sha>e3a102fb75ef112d064feebd2f9385385a445a06</Sha>
     </Dependency>
     <!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
     <Dependency Name="System.Collections.Immutable" Version="10.0.2">
@@ -76,29 +76,29 @@
     </Dependency>
   </ProductDependencies>
   <ToolsetDependencies>
-    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="10.0.0-beta.26168.1">
+    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="10.0.0-beta.26208.4">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>3907f62e877e105b6196b1bd9c309203d6362a0a</Sha>
+      <Sha>ecdd5c6a7986cafabbf6a322ea09a07736a01a0d</Sha>
     </Dependency>
-    <Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.26153.1">
+    <Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.26180.1">
       <Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
-      <Sha>b194351e54adc9538bb2a0b6a188f8f897fa223c</Sha>
+      <Sha>9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b</Sha>
     </Dependency>
-    <Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.26153.1">
+    <Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.26180.1">
       <Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
-      <Sha>b194351e54adc9538bb2a0b6a188f8f897fa223c</Sha>
+      <Sha>9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b</Sha>
     </Dependency>
-    <Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.26153.1">
+    <Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.26180.1">
       <Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
-      <Sha>b194351e54adc9538bb2a0b6a188f8f897fa223c</Sha>
+      <Sha>9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b</Sha>
     </Dependency>
-    <Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.26153.1">
+    <Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.26180.1">
       <Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
-      <Sha>b194351e54adc9538bb2a0b6a188f8f897fa223c</Sha>
+      <Sha>9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b</Sha>
     </Dependency>
-    <Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.26153.1">
+    <Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.26180.1">
       <Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
-      <Sha>b194351e54adc9538bb2a0b6a188f8f897fa223c</Sha>
+      <Sha>9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b</Sha>
     </Dependency>
   </ToolsetDependencies>
 </Dependencies>
diff --git a/eng/Versions.props b/eng/Versions.props
index b55d9a5626e..a6118a715f4 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -14,7 +14,7 @@
   <PropertyGroup>
     <!-- Don't use the built in support for pre-release iteration. The nuget repack task doesn't support
          the iteration format at the moment. https://github.com/dotnet/arcade/issues/15919 -->
-    <FSharpPreReleaseIteration>3</FSharpPreReleaseIteration>
+    <FSharpPreReleaseIteration>4</FSharpPreReleaseIteration>
     <PreReleaseVersionLabel>preview$(FSharpPreReleaseIteration)</PreReleaseVersionLabel>
     <!-- F# Version components -->
     <FSMajorVersion>11</FSMajorVersion>
@@ -63,7 +63,7 @@
   <PropertyGroup>
     <!-- These have to be in sync with latest release branch -->
     <VSMajorVersion>18</VSMajorVersion>
-    <VSMinorVersion>6</VSMinorVersion>
+    <VSMinorVersion>7</VSMinorVersion>
     <VSGeneralVersion>$(VSMajorVersion).0</VSGeneralVersion>
     <VSAssemblyVersionPrefix>$(VSMajorVersion).$(VSMinorVersion).0</VSAssemblyVersionPrefix>
     <VSAssemblyVersion>$(VSAssemblyVersionPrefix).0</VSAssemblyVersion>
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
index 5ce51840619..eaed6d87e65 100644
--- a/eng/common/core-templates/job/job.yml
+++ b/eng/common/core-templates/job/job.yml
@@ -24,12 +24,12 @@ parameters:
   enablePublishBuildArtifacts: false
   enablePublishBuildAssets: false
   enablePublishTestResults: false
+  enablePublishing: false
   enableBuildRetry: false
   mergeTestResults: false
   testRunTitle: ''
   testResultsFormat: ''
   name: ''
-  componentGovernanceSteps: []
   preSteps: []
   artifactPublishSteps: []
   runAsPublic: false
@@ -146,9 +146,6 @@ jobs:
   - ${{ each step in parameters.steps }}:
     - ${{ step }}
 
-  - ${{ each step in parameters.componentGovernanceSteps }}:
-    - ${{ step }}
-
   - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
     - template: /eng/common/core-templates/steps/cleanup-microbuild.yml
       parameters:
diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml
index c5788829a87..eefed3b667a 100644
--- a/eng/common/core-templates/job/onelocbuild.yml
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -52,13 +52,13 @@ jobs:
       # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
       ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
         name: AzurePipelines-EO
-        image: 1ESPT-Windows2022
+        image: 1ESPT-Windows2025
         demands: Cmd
         os: windows
       # If it's not devdiv, it's dnceng
       ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
         name: $(DncEngInternalBuildPool)
-        image: 1es-windows-2022
+        image: windows.vs2026.amd64
         os: windows
 
   steps:
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
index b955fac6e13..06f2eed0323 100644
--- a/eng/common/core-templates/job/publish-build-assets.yml
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -74,13 +74,13 @@ jobs:
     # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
     ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
       name: AzurePipelines-EO
-      image: 1ESPT-Windows2022
+      image: 1ESPT-Windows2025
       demands: Cmd
       os: windows
     # If it's not devdiv, it's dnceng
     ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
       name: NetCore1ESPool-Publishing-Internal
-      image: windows.vs2022.amd64
+      image: windows.vs2026.amd64
       os: windows
   steps:
   - ${{ if eq(parameters.is1ESPipeline, '') }}:
@@ -172,17 +172,18 @@ jobs:
             targetPath: '$(Build.ArtifactStagingDirectory)/MergedManifest.xml'
             artifactName: AssetManifests
             displayName: 'Publish Merged Manifest'
-            retryCountOnTaskFailure: 10 # for any logs being locked
-            sbomEnabled: false  # we don't need SBOM for logs
+            retryCountOnTaskFailure: 10 # for any files being locked
+            isProduction: false # just metadata for publishing
 
-    - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+    - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
       parameters:
         is1ESPipeline: ${{ parameters.is1ESPipeline }}
         args:
           displayName: Publish ReleaseConfigs Artifact
-          pathToPublish: '$(Build.StagingDirectory)/ReleaseConfigs'
-          publishLocation: Container
+          targetPath: '$(Build.StagingDirectory)/ReleaseConfigs'
           artifactName: ReleaseConfigs
+          retryCountOnTaskFailure: 10 # for any files being locked
+          isProduction: false # just metadata for publishing
 
     - ${{ if or(eq(parameters.publishAssetsImmediately, 'true'), eq(parameters.isAssetlessBuild, 'true')) }}:
       - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -218,4 +219,5 @@ jobs:
       - template: /eng/common/core-templates/steps/publish-logs.yml
         parameters:
           is1ESPipeline: ${{ parameters.is1ESPipeline }}
-          JobLabel: 'Publish_Artifacts_Logs'     
+          StageLabel: 'BuildAssetRegistry'
+          JobLabel: 'Publish_Artifacts_Logs'
diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml
index 01ada747665..cc8cce45278 100644
--- a/eng/common/core-templates/jobs/jobs.yml
+++ b/eng/common/core-templates/jobs/jobs.yml
@@ -43,6 +43,10 @@ parameters:
 
   artifacts: {}
   is1ESPipeline: ''
+
+  # Publishing version w/default.
+  publishingVersion: 3
+
   repositoryAlias: self
   officialBuildId: ''
 
@@ -102,6 +106,7 @@ jobs:
       parameters:
         is1ESPipeline: ${{ parameters.is1ESPipeline }}
         continueOnError: ${{ parameters.continueOnError }}
+        publishingVersion: ${{ parameters.publishingVersion }}
         dependsOn:
         - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:
           - ${{ each job in parameters.publishBuildAssetsDependsOn }}:
diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml
index b942a79ef02..905a6315e2d 100644
--- a/eng/common/core-templates/post-build/post-build.yml
+++ b/eng/common/core-templates/post-build/post-build.yml
@@ -9,6 +9,7 @@ parameters:
     default: 3
     values:
     - 3
+    - 4
 
   - name: BARBuildId
     displayName: BAR Build Id
@@ -120,7 +121,7 @@ stages:
         # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
         ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
           name: AzurePipelines-EO
-          image: 1ESPT-Windows2022
+          image: 1ESPT-Windows2025
           demands: Cmd
           os: windows
         # If it's not devdiv, it's dnceng
@@ -140,16 +141,30 @@ stages:
             PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
             is1ESPipeline: ${{ parameters.is1ESPipeline }}
 
-        - task: DownloadBuildArtifacts@0
-          displayName: Download Package Artifacts
-          inputs:
-            buildType: specific
-            buildVersionToDownload: specific
-            project: $(AzDOProjectName)
-            pipeline: $(AzDOPipelineId)
-            buildId: $(AzDOBuildId)
-            artifactName: PackageArtifacts
-            checkDownloadedFiles: true
+        - ${{ if ne(parameters.publishingInfraVersion, 4) }}:
+          - task: DownloadBuildArtifacts@0
+            displayName: Download Package Artifacts
+            inputs:
+              buildType: specific
+              buildVersionToDownload: specific
+              project: $(AzDOProjectName)
+              pipeline: $(AzDOPipelineId)
+              buildId: $(AzDOBuildId)
+              artifactName: PackageArtifacts
+              checkDownloadedFiles: true
+        - ${{ if eq(parameters.publishingInfraVersion, 4) }}:
+          - task: DownloadPipelineArtifact@2
+            displayName: Download Pipeline Artifacts (V4)
+            inputs:
+              itemPattern: '*/packages/**/*.nupkg'
+              targetPath: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+          - task: CopyFiles@2
+            displayName: Flatten packages to PackageArtifacts
+            inputs:
+              SourceFolder: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+              Contents: '**/*.nupkg'
+              TargetFolder: '$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+              flattenFolders: true
 
         - task: PowerShell@2
           displayName: Validate
@@ -164,14 +179,14 @@ stages:
         # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
         ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
           name: AzurePipelines-EO
-          image: 1ESPT-Windows2022
+          image: 1ESPT-Windows2025
           demands: Cmd
           os: windows
         # If it's not devdiv, it's dnceng
         ${{ else }}:
           ${{ if eq(parameters.is1ESPipeline, true) }}:        
             name: $(DncEngInternalBuildPool)
-            image: 1es-windows-2022
+            image: windows.vs2026.amd64
             os: windows
           ${{ else }}:
             name: $(DncEngInternalBuildPool)
@@ -183,16 +198,30 @@ stages:
             PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
             is1ESPipeline: ${{ parameters.is1ESPipeline }}
 
-        - task: DownloadBuildArtifacts@0
-          displayName: Download Package Artifacts
-          inputs:
-            buildType: specific
-            buildVersionToDownload: specific
-            project: $(AzDOProjectName)
-            pipeline: $(AzDOPipelineId)
-            buildId: $(AzDOBuildId)
-            artifactName: PackageArtifacts
-            checkDownloadedFiles: true
+        - ${{ if ne(parameters.publishingInfraVersion, 4) }}:
+          - task: DownloadBuildArtifacts@0
+            displayName: Download Package Artifacts
+            inputs:
+              buildType: specific
+              buildVersionToDownload: specific
+              project: $(AzDOProjectName)
+              pipeline: $(AzDOPipelineId)
+              buildId: $(AzDOBuildId)
+              artifactName: PackageArtifacts
+              checkDownloadedFiles: true
+        - ${{ if eq(parameters.publishingInfraVersion, 4) }}:
+          - task: DownloadPipelineArtifact@2
+            displayName: Download Pipeline Artifacts (V4)
+            inputs:
+              itemPattern: '*/packages/**/*.nupkg'
+              targetPath: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+          - task: CopyFiles@2
+            displayName: Flatten packages to PackageArtifacts
+            inputs:
+              SourceFolder: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+              Contents: '**/*.nupkg'
+              TargetFolder: '$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+              flattenFolders: true
 
         # This is necessary whenever we want to publish/restore to an AzDO private feed
         # Since sdk-task.ps1 tries to restore packages we need to do this authentication here
@@ -225,14 +254,14 @@ stages:
         # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
         ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
           name: AzurePipelines-EO
-          image: 1ESPT-Windows2022
+          image: 1ESPT-Windows2025
           demands: Cmd
           os: windows
         # If it's not devdiv, it's dnceng
         ${{ else }}:
           ${{ if eq(parameters.is1ESPipeline, true) }}:          
             name: $(DncEngInternalBuildPool)
-            image: 1es-windows-2022
+            image: windows.vs2026.amd64
             os: windows
           ${{ else }}:
             name: $(DncEngInternalBuildPool)
@@ -244,16 +273,30 @@ stages:
             PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
             is1ESPipeline: ${{ parameters.is1ESPipeline }}
 
-        - task: DownloadBuildArtifacts@0
-          displayName: Download Blob Artifacts
-          inputs:
-            buildType: specific
-            buildVersionToDownload: specific
-            project: $(AzDOProjectName)
-            pipeline: $(AzDOPipelineId)
-            buildId: $(AzDOBuildId)
-            artifactName: BlobArtifacts
-            checkDownloadedFiles: true
+        - ${{ if ne(parameters.publishingInfraVersion, 4) }}:
+          - task: DownloadBuildArtifacts@0
+            displayName: Download Blob Artifacts
+            inputs:
+              buildType: specific
+              buildVersionToDownload: specific
+              project: $(AzDOProjectName)
+              pipeline: $(AzDOPipelineId)
+              buildId: $(AzDOBuildId)
+              artifactName: BlobArtifacts
+              checkDownloadedFiles: true
+        - ${{ if eq(parameters.publishingInfraVersion, 4) }}:
+          - task: DownloadPipelineArtifact@2
+            displayName: Download Pipeline Artifacts (V4)
+            inputs:
+              itemPattern: '*/assets/**'
+              targetPath: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+          - task: CopyFiles@2
+            displayName: Flatten assets to BlobArtifacts
+            inputs:
+              SourceFolder: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+              Contents: '**/*'
+              TargetFolder: '$(Build.ArtifactStagingDirectory)/BlobArtifacts'
+              flattenFolders: true
 
         - task: PowerShell@2
           displayName: Validate
@@ -286,18 +329,18 @@ stages:
         # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
         ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
           name: AzurePipelines-EO
-          image: 1ESPT-Windows2022
+          image: 1ESPT-Windows2025
           demands: Cmd
           os: windows
         # If it's not devdiv, it's dnceng
         ${{ else }}:
           ${{ if eq(parameters.is1ESPipeline, true) }}:          
             name: NetCore1ESPool-Publishing-Internal
-            image: windows.vs2022.amd64
+            image: windows.vs2026.amd64
             os: windows
           ${{ else }}:
             name: NetCore1ESPool-Publishing-Internal
-            demands: ImageOverride -equals windows.vs2022.amd64          
+            demands: ImageOverride -equals windows.vs2026.amd64
       steps:
         - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
           parameters:
@@ -328,7 +371,7 @@ stages:
             scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1
             arguments: >
               -BuildId $(BARBuildId)
-              -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
+              -PublishingInfraVersion 3
               -AzdoToken '$(System.AccessToken)'
               -WaitPublishingFinish true
               -RequireDefaultChannels ${{ parameters.requireDefaultChannels }}
diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml
index a7abd58c4bb..6dfa99ec5e3 100644
--- a/eng/common/core-templates/post-build/setup-maestro-vars.yml
+++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -8,12 +8,11 @@ steps:
     - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
 
   - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
-    - task: DownloadBuildArtifacts@0
+    - task: DownloadPipelineArtifact@2
       displayName: Download Release Configs
       inputs:
-        buildType: current
         artifactName: ReleaseConfigs
-        checkDownloadedFiles: true
+        targetPath: '$(Build.StagingDirectory)/ReleaseConfigs'
 
   - task: AzureCLI@2
     name: setReleaseVars
diff --git a/eng/common/core-templates/steps/component-governance.yml b/eng/common/core-templates/steps/component-governance.yml
deleted file mode 100644
index cf0649aa956..00000000000
--- a/eng/common/core-templates/steps/component-governance.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-parameters:
-  disableComponentGovernance: false
-  componentGovernanceIgnoreDirectories: ''
-  is1ESPipeline: false
-  displayName: 'Component Detection'
-
-steps:
-- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
-  - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
-    displayName: Set skipComponentGovernanceDetection variable
-- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
-  - task: ComponentGovernanceComponentDetection@0
-    continueOnError: true
-    displayName: ${{ parameters.displayName }}
-    inputs:
-      ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml
index c05f6502797..aad0a8aeda3 100644
--- a/eng/common/core-templates/steps/generate-sbom.yml
+++ b/eng/common/core-templates/steps/generate-sbom.yml
@@ -1,54 +1,14 @@
-# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
-# PackageName - The name of the package this SBOM represents.
-# PackageVersion - The version of the package this SBOM represents. 
-# ManifestDirPath - The path of the directory where the generated manifest files will be placed
-# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
-
 parameters:
-  PackageVersion: 10.0.0
-  BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
-  PackageName: '.NET'
-  ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
-  IgnoreDirectories: ''
-  sbomContinueOnError: true
-  is1ESPipeline: false
-  # disable publishArtifacts if some other step is publishing the artifacts (like job.yml).
-  publishArtifacts: true
+  PackageVersion: unused
+  BuildDropPath: unused
+  PackageName: unused
+  ManifestDirPath: unused
+  IgnoreDirectories: unused
+  sbomContinueOnError: unused
+  is1ESPipeline: unused
+  publishArtifacts: unused
 
 steps:
-- task: PowerShell@2 
-  displayName: Prep for SBOM generation in (Non-linux)
-  condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
-  inputs: 
-    filePath: ./eng/common/generate-sbom-prep.ps1
-    arguments: ${{parameters.manifestDirPath}}
-
-# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
 - script: |
-    chmod +x ./eng/common/generate-sbom-prep.sh
-    ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
-  displayName: Prep for SBOM generation in (Linux)
-  condition: eq(variables['Agent.Os'], 'Linux')
-  continueOnError: ${{ parameters.sbomContinueOnError }}
-
-- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
-  displayName: 'Generate SBOM manifest'
-  continueOnError: ${{ parameters.sbomContinueOnError }}
-  inputs:
-      PackageName: ${{ parameters.packageName }}
-      BuildDropPath: ${{ parameters.buildDropPath }}
-      PackageVersion: ${{ parameters.packageVersion }}
-      ManifestDirPath: ${{ parameters.manifestDirPath }}/$(ARTIFACT_NAME)
-      ${{ if ne(parameters.IgnoreDirectories, '') }}:
-        AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
-
-- ${{ if eq(parameters.publishArtifacts, 'true')}}:
-  - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
-    parameters:
-      is1ESPipeline: ${{ parameters.is1ESPipeline }}
-      args:
-        displayName: Publish SBOM manifest
-        continueOnError: ${{parameters.sbomContinueOnError}}
-        targetPath: '${{ parameters.manifestDirPath }}'
-        artifactName: $(ARTIFACT_NAME)
-
+    echo "##vso[task.logissue type=warning]Including generate-sbom.yml is deprecated, SBOM generation is handled 1ES PT now. Remove this include."
+  displayName: Issue generate-sbom.yml deprecation warning
diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml
index a9ea99ba6aa..4eed0312b80 100644
--- a/eng/common/core-templates/steps/publish-logs.yml
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -50,13 +50,14 @@ steps:
     TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
   condition: always()
 
-- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
   parameters:
     is1ESPipeline: ${{ parameters.is1ESPipeline }}
     args:
       displayName: Publish Logs
-      pathToPublish: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
-      publishLocation: Container
-      artifactName: PostBuildLogs
+      targetPath: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
+      artifactName: PostBuildLogs_${{ parameters.StageLabel }}_${{ parameters.JobLabel }}_Attempt$(System.JobAttempt)
       continueOnError: true
       condition: always()
+      retryCountOnTaskFailure: 10 # for any files being locked
+      isProduction: false # logs are non-production artifacts
diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml
index b9c86c18ae4..09ae5cd73ae 100644
--- a/eng/common/core-templates/steps/source-build.yml
+++ b/eng/common/core-templates/steps/source-build.yml
@@ -62,4 +62,4 @@ steps:
       artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
       continueOnError: true
       condition: succeededOrFailed()
-      sbomEnabled: false  # we don't need SBOM for logs
+      isProduction: false # logs are non-production artifacts
diff --git a/eng/common/generate-sbom-prep.ps1 b/eng/common/generate-sbom-prep.ps1
deleted file mode 100644
index a0c7d792a76..00000000000
--- a/eng/common/generate-sbom-prep.ps1
+++ /dev/null
@@ -1,29 +0,0 @@
-Param(
-    [Parameter(Mandatory=$true)][string] $ManifestDirPath    # Manifest directory where sbom will be placed
-)
-
-. $PSScriptRoot\pipeline-logging-functions.ps1
-
-# Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly
-# with their own overwriting ours. So we create it as a sub directory of the requested manifest path.
-$ArtifactName = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM"
-$SafeArtifactName = $ArtifactName -replace '["/:<>\\|?@*"() ]', '_'
-$SbomGenerationDir = Join-Path $ManifestDirPath $SafeArtifactName
-
-Write-Host "Artifact name before : $ArtifactName"
-Write-Host "Artifact name after : $SafeArtifactName"
-
-Write-Host "Creating dir $ManifestDirPath"
-
-# create directory for sbom manifest to be placed
-if (!(Test-Path -path $SbomGenerationDir))
-{
-  New-Item -ItemType Directory -path $SbomGenerationDir
-  Write-Host "Successfully created directory $SbomGenerationDir"
-}
-else{
-  Write-PipelineTelemetryError -category 'Build'  "Unable to create sbom folder."
-}
-
-Write-Host "Updating artifact name"
-Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$SafeArtifactName"
diff --git a/eng/common/generate-sbom-prep.sh b/eng/common/generate-sbom-prep.sh
deleted file mode 100755
index b8ecca72bbf..00000000000
--- a/eng/common/generate-sbom-prep.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-
-source="${BASH_SOURCE[0]}"
-
-# resolve $SOURCE until the file is no longer a symlink
-while [[ -h $source ]]; do
-  scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
-  source="$(readlink "$source")"
-
-  # if $source was a relative symlink, we need to resolve it relative to the path where the
-  # symlink file was located
-  [[ $source != /* ]] && source="$scriptroot/$source"
-done
-scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
-. $scriptroot/pipeline-logging-functions.sh
-
-
-# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts.
-artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM"
-safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}"
-manifest_dir=$1
-
-# Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly
-# with their own overwriting ours. So we create it as a sub directory of the requested manifest path.
-sbom_generation_dir="$manifest_dir/$safe_artifact_name"
-
-if [ ! -d "$sbom_generation_dir" ] ; then
-  mkdir -p "$sbom_generation_dir"
-  echo "Sbom directory created." $sbom_generation_dir
-else
-  Write-PipelineTelemetryError -category 'Build'  "Unable to create sbom folder."
-fi
-
-echo "Artifact name before : "$artifact_name
-echo "Artifact name after : "$safe_artifact_name
-export ARTIFACT_NAME=$safe_artifact_name
-echo "##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name"
-
-exit 0
diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md
index 4bf4cf41bd7..e2b07a865f1 100644
--- a/eng/common/template-guidance.md
+++ b/eng/common/template-guidance.md
@@ -82,7 +82,6 @@ eng\common\
             publish-build-artifacts.yml      (logic)
             publish-pipeline-artifacts.yml   (logic)
             component-governance.yml         (shim)
-            generate-sbom.yml                (shim)
             publish-logs.yml                 (shim)
             retain-build.yml                 (shim)
             send-to-helix.yml                (shim)
@@ -107,7 +106,6 @@ eng\common\
             setup-maestro-vars.yml           (logic)
         steps\
             component-governance.yml         (logic)
-            generate-sbom.yml                (logic)
             publish-build-artifacts.yml      (redirect)
             publish-logs.yml                 (logic)
             publish-pipeline-artifacts.yml   (redirect)
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index 92a0664f564..d68e9fbc265 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -1,24 +1,15 @@
 parameters:
-# Sbom related params
-  enableSbom: true
   runAsPublic: false
-  PackageVersion: 9.0.0
-  BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
+# Sbom related params, unused now and can eventually be removed
+  enableSbom: unused
+  PackageVersion: unused
+  BuildDropPath: unused
 
 jobs:
 - template: /eng/common/core-templates/job/job.yml
   parameters:
     is1ESPipeline: true
 
-    componentGovernanceSteps:
-    - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
-      - template: /eng/common/templates/steps/generate-sbom.yml
-        parameters:
-          PackageVersion: ${{ parameters.packageVersion }}
-          BuildDropPath: ${{ parameters.buildDropPath }}
-          ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
-          publishArtifacts: false
-
     # publish artifacts
     # for 1ES managed templates, use the templateContext.output to handle multiple outputs.
     templateContext:
@@ -26,12 +17,19 @@ jobs:
       outputs:
       - ${{ if ne(parameters.artifacts.publish, '') }}:
         - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
-          - output: buildArtifacts
+          - output: pipelineArtifact
             displayName: Publish pipeline artifacts
-            PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
-            ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
-            condition: always()
-            retryCountOnTaskFailure: 10 # for any logs being locked
+            targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+            artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
+            condition: succeeded()
+            retryCountOnTaskFailure: 10 # for any files being locked
+            continueOnError: true
+          - output: pipelineArtifact
+            displayName: Publish pipeline artifacts
+            targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+            artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}_Attempt$(System.JobAttempt)
+            condition: not(succeeded())
+            retryCountOnTaskFailure: 10 # for any files being locked
             continueOnError: true
         - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
           - output: pipelineArtifact
@@ -40,18 +38,18 @@ jobs:
             displayName: 'Publish logs'
             continueOnError: true
             condition: always()
-            retryCountOnTaskFailure: 10 # for any logs being locked
-            sbomEnabled: false  # we don't need SBOM for logs
+            retryCountOnTaskFailure: 10 # for any files being locked
+            isProduction: false # logs are non-production artifacts
 
       - ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}:
-        - output: buildArtifacts
+        - output: pipelineArtifact
           displayName: Publish Logs
-          PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
-          publishLocation: Container
-          ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
+          targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
+          artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
           continueOnError: true
           condition: always()
-          sbomEnabled: false  # we don't need SBOM for logs
+          retryCountOnTaskFailure: 10 # for any files being locked
+          isProduction: false # logs are non-production artifacts
 
       - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
         - output: pipelineArtifact
@@ -59,14 +57,20 @@ jobs:
           artifactName: 'BuildConfiguration'
           displayName: 'Publish build retry configuration'
           continueOnError: true
-          sbomEnabled: false  # we don't need SBOM for BuildConfiguration
+          retryCountOnTaskFailure: 10 # for any files being locked
+          isProduction: false # BuildConfiguration is a non-production artifact
 
-      - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
+      # V4 publishing: automatically publish staged artifacts as a pipeline artifact.
+      # The artifact name matches the SDK's FutureArtifactName ($(System.PhaseName)_Artifacts),
+      # which is encoded in the asset manifest for downstream publishing to discover.
+      # Jobs can opt in by setting enablePublishing: true.
+      - ${{ if and(eq(parameters.publishingVersion, 4), eq(parameters.enablePublishing, 'true')) }}:
         - output: pipelineArtifact
-          displayName: Publish SBOM manifest
+          displayName: 'Publish V4 pipeline artifacts'
+          targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+          artifactName: '$(System.PhaseName)_Artifacts'
           continueOnError: true
-          targetPath: $(Build.ArtifactStagingDirectory)/sbom
-          artifactName: $(ARTIFACT_NAME)
+          retryCountOnTaskFailure: 10 # for any files being locked
 
       # add any outputs provided via root yaml
       - ${{ if ne(parameters.templateContext.outputs, '') }}:
diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml
deleted file mode 100644
index 30bb3985ca2..00000000000
--- a/eng/common/templates-official/steps/component-governance.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-steps:
-- template: /eng/common/core-templates/steps/component-governance.yml
-  parameters:
-    is1ESPipeline: true
-
-    ${{ each parameter in parameters }}:
-      ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
index 172f9f0fdc9..9e5981365e5 100644
--- a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
+++ b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
@@ -24,5 +24,7 @@ steps:
       artifactName: ${{ parameters.args.artifactName }}
     ${{ if parameters.args.properties }}:
       properties: ${{ parameters.args.properties }}
-    ${{ if parameters.args.sbomEnabled }}:
+    ${{ if ne(parameters.args.sbomEnabled, '') }}:
       sbomEnabled: ${{ parameters.args.sbomEnabled }}
+    ${{ if ne(parameters.args.isProduction, '') }}:
+      isProduction: ${{ parameters.args.isProduction }}
diff --git a/eng/common/templates-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml
index 1f308b24efc..2cc3ae305d5 100644
--- a/eng/common/templates-official/variables/pool-providers.yml
+++ b/eng/common/templates-official/variables/pool-providers.yml
@@ -23,7 +23,7 @@
 #
 #        pool:
 #           name: $(DncEngInternalBuildPool)
-#           image: 1es-windows-2022
+#           image: windows.vs2026.amd64
 
 variables:
   # Coalesce the target and source branches so we know when a PR targets a release branch
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 238fa0818f7..5e261f34db4 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -1,12 +1,12 @@
 parameters: 
   enablePublishBuildArtifacts: false
-  disableComponentGovernance: ''
-  componentGovernanceIgnoreDirectories: ''
-# Sbom related params
-  enableSbom: true
   runAsPublic: false
-  PackageVersion: 9.0.0
-  BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
+# CG related params, unused now and can eventually be removed
+  disableComponentGovernance: unused
+# Sbom related params, unused now and can eventually be removed
+  enableSbom: unused
+  PackageVersion: unused
+  BuildDropPath: unused
 
 jobs:
 - template: /eng/common/core-templates/job/job.yml
@@ -21,32 +21,34 @@ jobs:
     - ${{ each step in parameters.steps }}:
       - ${{ step }}
 
-    componentGovernanceSteps:
-    - template: /eng/common/templates/steps/component-governance.yml
-      parameters:
-        ${{ if eq(parameters.disableComponentGovernance, '') }}:
-          ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}:
-            disableComponentGovernance: false
-          ${{ else }}:
-            disableComponentGovernance: true
-        ${{ else }}:
-          disableComponentGovernance: ${{ parameters.disableComponentGovernance }}
-        componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
+    # we don't run CG in public
+    - ${{ if eq(variables['System.TeamProject'], 'public') }}:
+      - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
+        displayName: Set skipComponentGovernanceDetection variable
 
     artifactPublishSteps:
     - ${{ if ne(parameters.artifacts.publish, '') }}:
       - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
-        - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+        - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
           parameters:
             is1ESPipeline: false
             args:
               displayName: Publish pipeline artifacts
-              pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
-              publishLocation: Container
+              targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
               artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
               continueOnError: true
-              condition: always()
-              retryCountOnTaskFailure: 10 # for any logs being locked
+              condition: succeeded()
+              retryCountOnTaskFailure: 10 # for any files being locked
+        - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
+          parameters:
+            is1ESPipeline: false
+            args:
+              displayName: Publish pipeline artifacts
+              targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+              artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}_Attempt$(System.JobAttempt)
+              continueOnError: true
+              condition: not(succeeded())
+              retryCountOnTaskFailure: 10 # for any files being locked
       - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
         - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
           parameters:
@@ -57,20 +59,19 @@ jobs:
               displayName: 'Publish logs'
               continueOnError: true
               condition: always()
-              retryCountOnTaskFailure: 10 # for any logs being locked
-              sbomEnabled: false  # we don't need SBOM for logs
+              retryCountOnTaskFailure: 10 # for any files being locked
 
     - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
-      - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+      - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
         parameters:
           is1ESPipeline: false
           args:
             displayName: Publish Logs
-            pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
-            publishLocation: Container
+            targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
             artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
             continueOnError: true
             condition: always()
+            retryCountOnTaskFailure: 10 # for any files being locked
 
     - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
       - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
@@ -81,4 +82,4 @@ jobs:
             artifactName: 'BuildConfiguration'
             displayName: 'Publish build retry configuration'
             continueOnError: true
-            sbomEnabled: false  # we don't need SBOM for BuildConfiguration
+            retryCountOnTaskFailure: 10 # for any files being locked
diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml
deleted file mode 100644
index c12a5f8d21d..00000000000
--- a/eng/common/templates/steps/component-governance.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-steps:
-- template: /eng/common/core-templates/steps/component-governance.yml
-  parameters:
-    is1ESPipeline: false
-
-    ${{ each parameter in parameters }}:
-      ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/variables/pool-providers.yml b/eng/common/templates/variables/pool-providers.yml
index 18693ea120d..587770f0add 100644
--- a/eng/common/templates/variables/pool-providers.yml
+++ b/eng/common/templates/variables/pool-providers.yml
@@ -23,7 +23,7 @@
 #
 #        pool:
 #           name: $(DncEngInternalBuildPool)
-#           demands: ImageOverride -equals windows.vs2022.amd64
+#           demands: ImageOverride -equals windows.vs2026.amd64
 variables:
   - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
     - template: /eng/common/templates-official/variables/pool-providers.yml
diff --git a/global.json b/global.json
index 1b2af8d425c..bd485523f54 100644
--- a/global.json
+++ b/global.json
@@ -22,7 +22,7 @@
     "xcopy-msbuild": "18.0.0"
   },
   "msbuild-sdks": {
-    "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26168.1",
+    "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26208.4",
     "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2"
   }
 }
diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs
index ba62a69e4be..a7352914720 100755
--- a/src/Compiler/Checking/AttributeChecking.fs
+++ b/src/Compiler/Checking/AttributeChecking.fs
@@ -639,6 +639,27 @@ let PropInfoIsUnseen _m allowObsolete pinfo =
         CheckProvidedAttributesForUnseen (pi.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) m
 #endif
 
+/// Indicate if an ILFieldInfo has 'Obsolete' attribute.
+/// Used to suppress the item in intellisense.
+let ILFieldInfoIsUnseen (finfo: ILFieldInfo) =
+    match finfo with
+    | ILFieldInfo(_, fdef) -> CheckILAttributesForUnseen fdef.CustomAttrs
+#if !NO_TYPEPROVIDERS
+    | ProvidedField(_amap, fi, m) ->
+        CheckProvidedAttributesForUnseen (fi.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) m
+#endif
+
+/// Indicate if an EventInfo has 'Obsolete' or 'CompilerMessageAttribute'.
+/// Used to suppress the item in intellisense.
+let EventInfoIsUnseen allowObsolete (einfo: EventInfo) =
+    match einfo with
+    | ILEvent(ILEventInfo(_, ilEventDef)) -> CheckILAttributesForUnseen ilEventDef.CustomAttrs
+    | FSEvent(g, _, addValRef, _) -> CheckFSharpAttributesForUnseen g addValRef.Attribs allowObsolete
+#if !NO_TYPEPROVIDERS
+    | ProvidedEvent(_amap, ei, m) ->
+        CheckProvidedAttributesForUnseen (ei.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) m
+#endif
+
 /// Check the attributes on a union case, returning errors and warnings as data.
 let CheckUnionCaseAttributes g (x:UnionCaseRef) m =
     trackErrors {
diff --git a/src/Compiler/Checking/AttributeChecking.fsi b/src/Compiler/Checking/AttributeChecking.fsi
index c8198e4a985..564957e1bd7 100644
--- a/src/Compiler/Checking/AttributeChecking.fsi
+++ b/src/Compiler/Checking/AttributeChecking.fsi
@@ -101,6 +101,10 @@ val MethInfoIsUnseen: g: TcGlobals -> m: range -> ty: TType -> minfo: MethInfo -
 
 val PropInfoIsUnseen: _m: 'a -> allowObsolete: bool -> pinfo: PropInfo -> bool
 
+val ILFieldInfoIsUnseen: finfo: ILFieldInfo -> bool
+
+val EventInfoIsUnseen: allowObsolete: bool -> einfo: EventInfo -> bool
+
 val CheckEntityAttributes: g: TcGlobals -> tcref: TyconRef -> m: range -> OperationResult<unit>
 
 val CheckUnionCaseAttributes: g: TcGlobals -> x: UnionCaseRef -> m: range -> OperationResult<unit>
diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs
index 3fd84ee6c09..5a6bbf619fa 100644
--- a/src/Compiler/Checking/Expressions/CheckExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs
@@ -5522,7 +5522,16 @@ and TcStmtThatCantBeCtorBody (cenv: cenv) env tpenv synExpr =
 and TcStmt (cenv: cenv) env tpenv synExpr =
     let g = cenv.g
     let expr, ty, tpenv = TcExprOfUnknownType cenv env tpenv synExpr
-    let m = synExpr.Range
+
+    // Use the range of the last expression in a sequential chain for warnings,
+    // so that "expression is ignored" diagnostics point at the offending expression
+    // rather than the entire sequential body. See https://github.com/dotnet/fsharp/issues/5735
+    let rec lastExprRange (e: SynExpr) =
+        match e with
+        | SynExpr.Sequential(expr2 = expr2) -> lastExprRange expr2
+        | _ -> e.Range
+
+    let m = lastExprRange synExpr
     let wasUnit = UnifyUnitType cenv env m ty expr
     if wasUnit then
         expr, tpenv
@@ -13146,7 +13155,11 @@ let TcAndPublishValSpec (cenv: cenv, env, containerInfo: ContainerInfo, declKind
 
         let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs
         let xmlDoc = xmlDoc.ToXmlDoc(checkXmlDocs, paramNames)
-        let vspec = MakeAndPublishVal cenv env (altActualParent, true, declKind, ValNotInRecScope, valscheme, attrs, xmlDoc, literalValue, false)
+        let isGeneratedEventVal =
+            CompileAsEvent g attrs
+            && (id.idText.StartsWithOrdinal("add_") || id.idText.StartsWithOrdinal("remove_"))
+
+        let vspec = MakeAndPublishVal cenv env (altActualParent, true, declKind, ValNotInRecScope, valscheme, attrs, xmlDoc, literalValue, isGeneratedEventVal)
 
         PublishArguments cenv env vspec synValSig allDeclaredTypars.Length
 
diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs
index 55ab3c9219b..07d0ea4743b 100644
--- a/src/Compiler/Checking/NameResolution.fs
+++ b/src/Compiler/Checking/NameResolution.fs
@@ -4393,6 +4393,8 @@ let ItemIsUnseen ad g amap m allowObsolete item =
         isUnseenNameOfOperator || IsValUnseen ad g m allowObsolete x
     | Item.UnionCase(x, _) -> IsUnionCaseUnseen ad g amap m allowObsolete x.UnionCaseRef
     | Item.ExnCase x -> IsTyconUnseen ad g amap m allowObsolete x
+    | Item.ILField finfo -> not allowObsolete && ILFieldInfoIsUnseen finfo
+    | Item.Event einfo -> not allowObsolete && EventInfoIsUnseen allowObsolete einfo
     | _ -> false
 
 let ItemOfTyconRef ncenv m (x: TyconRef) =
@@ -4467,7 +4469,8 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
             ncenv.InfoReader.GetEventInfosOfType(None, ad, m, ty)
             |> List.filter (fun x ->
                 IsStandardEventInfo ncenv.InfoReader m ad x &&
-                x.IsStatic = statics)
+                x.IsStatic = statics &&
+                (allowObsolete || not (EventInfoIsUnseen allowObsolete x)))
         else []
 
     let nestedTypes =
@@ -4482,7 +4485,8 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
         |> List.filter (fun x ->
             not x.IsSpecialName &&
             x.IsStatic = statics &&
-            IsILFieldInfoAccessible g amap m ad x)
+            IsILFieldInfoAccessible g amap m ad x &&
+            (allowObsolete || not (ILFieldInfoIsUnseen x)))
 
     let qinfos =
         ncenv.InfoReader.GetTraitInfosInType None ty
diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs
index b4f800e185a..1a38e10f42b 100644
--- a/src/Compiler/Checking/infos.fs
+++ b/src/Compiler/Checking/infos.fs
@@ -2049,7 +2049,10 @@ type PropInfo =
     /// Indicates if this is an F# property compiled as a CLI event, e.g. a [<CLIEvent>] property.
     member x.IsFSharpEventProperty =
         match x with
-        | FSProp(g, _, Some vref, None)  -> vref.IsFSharpEventProperty g
+        | FSProp(g, _, getterOpt, setterOpt) ->
+            match getterOpt, setterOpt with
+            | Some vref, _ | None, Some vref -> vref.IsFSharpEventProperty g
+            | None, None -> false
 #if !NO_TYPEPROVIDERS
         | ProvidedProp _ -> false
 #endif
diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs
index 14a966ad068..4e3452a2d8e 100644
--- a/src/Compiler/CodeGen/IlxGen.fs
+++ b/src/Compiler/CodeGen/IlxGen.fs
@@ -10903,6 +10903,13 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) =
         | SynMemberKind.Constructor
         | SynMemberKind.Member ->
             let mdef = mdef.With(customAttrs = mkILCustomAttrs ilAttrs)
+
+            let mdef =
+                if vref.Deref.val_flags.IsGeneratedEventVal then
+                    mdef.WithSpecialName
+                else
+                    mdef
+
             [ mdef ], [], []
         | SynMemberKind.PropertyGetSet -> error (Error(FSComp.SR.ilUnexpectedGetSetAnnotation (), m))
         | SynMemberKind.PropertySet
@@ -11927,6 +11934,17 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
                     //
                     // Also discard the F#-compiler supplied implementation of the Empty, IsEmpty, Value and None properties.
 
+                    let nullaryCaseNames =
+                        if cuinfo.HasHelpers = AllHelpers || cuinfo.HasHelpers = NoHelpers then
+                            cuinfo.UnionCases
+                            |> Array.choose (fun alt -> if alt.IsNullary then Some alt.Name else None)
+                            |> Set.ofArray
+                        else
+                            Set.empty
+
+                    let isNullaryCaseClash name =
+                        not nullaryCaseNames.IsEmpty && nullaryCaseNames.Contains name
+
                     let tdefDiscards =
                         Some(
                             (fun (md: ILMethodDef) ->
@@ -11935,7 +11953,11 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
                                 || (cuinfo.HasHelpers = SpecialFSharpOptionHelpers
                                     && (md.Name = "get_Value" || md.Name = "get_None" || md.Name = "Some"))
                                 || (cuinfo.HasHelpers = AllHelpers
-                                    && (md.Name.StartsWith("get_Is") && not (tdef2.Methods.FindByName(md.Name).IsEmpty)))),
+                                    && (md.Name.StartsWith("get_Is") && not (tdef2.Methods.FindByName(md.Name).IsEmpty)))
+                                || (md.Name.StartsWith("get_")
+                                    && md.Name.Length > 4
+                                    && isNullaryCaseClash (md.Name.Substring(4))
+                                    && not (tdef2.Methods.FindByName(md.Name).IsEmpty))),
 
                             (fun (pd: ILPropertyDef) ->
                                 (cuinfo.HasHelpers = SpecialFSharpListHelpers
@@ -11943,7 +11965,10 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
                                 || (cuinfo.HasHelpers = SpecialFSharpOptionHelpers
                                     && (pd.Name = "Value" || pd.Name = "None"))
                                 || (cuinfo.HasHelpers = AllHelpers
-                                    && (pd.Name.StartsWith("Is") && not (tdef2.Properties.LookupByName(pd.Name).IsEmpty))))
+                                    && (pd.Name.StartsWith("Is") && not (tdef2.Properties.LookupByName(pd.Name).IsEmpty)))
+                                || (isNullaryCaseClash pd.Name
+                                    && (not (tdef2.Properties.LookupByName(pd.Name).IsEmpty)
+                                        || not (tdef2.Methods.FindByName("get_" + pd.Name).IsEmpty))))
                         )
 
                     tdef2, tdefDiscards
diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs
index 996a21d0107..08252dd76d5 100644
--- a/src/Compiler/Symbols/Symbols.fs
+++ b/src/Compiler/Symbols/Symbols.fs
@@ -1906,6 +1906,8 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
     member _.IsEvent = 
         match d with 
         | E _ -> true
+        | P p when p.IsFSharpEventProperty -> true
+        | V v when v.IsFSharpEventProperty cenv.g -> true
         | _ -> false
 
     member _.EventForFSharpProperty = 
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index 4791cc1d429..7da5a63eef2 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -9689,7 +9689,9 @@ let XmlDocSigOfVal g full path (v: Val) =
                 | SynMemberKind.Member -> "M:", v.CompiledName g.CompilerGlobalState
                 | SynMemberKind.PropertyGetSet 
                 | SynMemberKind.PropertySet
-                | SynMemberKind.PropertyGet -> "P:", v.PropertyName
+                | SynMemberKind.PropertyGet -> 
+                    let prefix = if attribsHaveValFlag g WellKnownValAttributes.CLIEventAttribute v.Attribs then "E:" else "P:"
+                    prefix, v.PropertyName
 
             let path = if v.HasDeclaringEntity then prependPath path v.DeclaringEntity.CompiledName else path
 
diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi
index 59e6377ffe4..503e3ee6900 100644
--- a/src/FSharp.Core/array.fsi
+++ b/src/FSharp.Core/array.fsi
@@ -1895,7 +1895,8 @@ module Array =
 
     /// <summary>Returns the greatest of all elements of the array, compared via Operators.max on the function result.</summary>
     ///
-    /// <remarks>Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array.</remarks>
+    /// <remarks>Returns the first maximal element of the array if there are multiple equal maximum elements.
+    /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array.</remarks>
     ///
     /// <param name="projection">The function to transform the elements into a type supporting comparison.</param>
     /// <param name="array">The input array.</param>
@@ -1958,7 +1959,8 @@ module Array =
 
     /// <summary>Returns the lowest of all elements of the array, compared via Operators.min on the function result.</summary>
     ///
-    /// <remarks>Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array.</remarks>
+    /// <remarks>Returns the first minimal element of the array if there are multiple equal minimal elements.
+    /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array.</remarks>
     ///
     /// <param name="projection">The function to transform the elements into a type supporting comparison.</param>
     /// <param name="array">The input array.</param>
diff --git a/src/FSharp.Core/list.fsi b/src/FSharp.Core/list.fsi
index a16c3c1e328..af7ddf2aeef 100644
--- a/src/FSharp.Core/list.fsi
+++ b/src/FSharp.Core/list.fsi
@@ -1573,7 +1573,8 @@ module List =
 
     /// <summary>Returns the greatest of all elements of the list, compared via Operators.max on the function result.</summary>
     ///
-    /// <remarks>Raises <see cref="T:System.ArgumentException"/> if <c>list</c> is empty. This is an O(n) operation, where n is the length of the list.</remarks>
+    /// <remarks>Returns the first maximal element of the list if there are multiple equal maximum elements.
+    /// Raises <see cref="T:System.ArgumentException"/> if <c>list</c> is empty. This is an O(n) operation, where n is the length of the list.</remarks>
     /// <param name="projection">The function to transform the list elements into the type to be compared.</param>
     /// <param name="list">The input list.</param>
     ///
@@ -1632,7 +1633,8 @@ module List =
 
     /// <summary>Returns the lowest of all elements of the list, compared via Operators.min on the function result</summary>
     ///
-    /// <remarks>Raises <see cref="T:System.ArgumentException"/> if <c>list</c> is empty. This is an O(n) operation, where n is the length of the list.</remarks>
+    /// <remarks>Returns the first minimal element of the list if there are multiple equal minimal elements.
+    /// Raises <see cref="T:System.ArgumentException"/> if <c>list</c> is empty. This is an O(n) operation, where n is the length of the list.</remarks>
     /// <param name="projection">The function to transform list elements into the type to be compared.</param>
     /// <param name="list">The input list.</param>
     ///
diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi
index b793b63e6de..86f09996263 100644
--- a/src/FSharp.Core/seq.fsi
+++ b/src/FSharp.Core/seq.fsi
@@ -1779,6 +1779,8 @@ module Seq =
 
     /// <summary>Returns the greatest of all elements of the sequence, compared via Operators.max on the function result.</summary>
     ///
+    /// <remarks>Returns the first maximal element of the sequence if there are multiple equal maximum elements.
+    /// This is an O(n) operation, where n is the length of the sequence.</remarks>
     /// <param name="projection">A function to transform items from the input sequence into comparable keys.</param>
     /// <param name="source">The input sequence.</param>
     ///
@@ -1804,8 +1806,6 @@ module Seq =
     /// </code>
     /// Throws <c>System.ArgumentException</c>.
     /// </example>
-    ///
-    /// <remarks>This is an O(n) operation, where n is the length of the sequence.</remarks>
     [<CompiledName("MaxBy")>]
     val inline maxBy: projection: ('T -> 'U) -> source: seq<'T> -> 'T when 'U: comparison
 
@@ -1842,6 +1842,9 @@ module Seq =
 
     /// <summary>Returns the lowest of all elements of the sequence, compared via Operators.min on the function result.</summary>
     ///
+    /// <remarks>Returns the first minimal element of the sequence if there are multiple equal minimal elements.
+    /// This is an O(n) operation, where n is the length of the sequence.</remarks>
+    ///
     /// <param name="projection">A function to transform items from the input sequence into comparable keys.</param>
     /// <param name="source">The input sequence.</param>
     ///
@@ -1867,8 +1870,6 @@ module Seq =
     /// </code>
     /// Throws <c>System.ArgumentException</c>.
     /// </example>
-    ///
-    /// <remarks>This is an O(n) operation, where n is the length of the sequence.</remarks>
     [<CompiledName("MinBy")>]
     val inline minBy: projection: ('T -> 'U) -> source: seq<'T> -> 'T when 'U: comparison
 
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/Signatures.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/Signatures.fs
index 1dc0799cb8e..b0556b532aa 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/Signatures.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/Signatures.fs
@@ -140,3 +140,29 @@ module SignatureConformance =
         |> withDiagnosticMessageMatches "GetEnumerator"
         |> withDiagnosticMessageDoesntMatch "The compiled names differ"
         |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/11331
+    [<Fact>]
+    let ``Issue 11331 - Public constructor taking internal type should report FS0410 in signature`` () =
+        Fsi
+            """
+module WrongAccessibility.Library
+
+type internal A = class end
+
+type B =
+    new: a: A -> B
+            """
+        |> withAdditionalSourceFile (
+            FsSource
+                """
+module WrongAccessibility.Library
+
+type internal A = class end
+
+type B(a: A) = class end
+            """
+        )
+        |> compile
+        |> shouldFail
+        |> withErrorCode 0410
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs
index 42eb6c29fb4..5fe08685248 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs
@@ -1831,3 +1831,29 @@ let _x3 = curryN f3 1 2 3
         FSharp "module T\nopen CsLib\nlet _ = IP.Get()" |> asExe |> withOptions iwsamWarnings |> withReferences [csLib]
         |> compileAndRun |> shouldSucceed
 
+    // https://github.com/dotnet/fsharp/issues/15987
+    [<Fact>]
+    let ``Issue 15987 - SRTP overload resolution returns correct value for typed argument`` () =
+        FSharp """
+module Test
+
+type A = A with
+    static member ($) (A, a: float  ) = 0.0
+    static member ($) (A, a: decimal) = 0M
+    static member ($) (A, a: 't     ) = 0
+
+let inline call x = ($) A x
+
+// Verify correct overload is selected: float argument should use the float overload
+let resultFloat: float = call 42.0
+let resultDecimal: decimal = call 42M
+let resultInt: int = call 42
+
+if resultFloat <> 0.0 then failwith $"Expected 0.0 but got {resultFloat}"
+if resultDecimal <> 0M then failwith $"Expected 0M but got {resultDecimal}"
+if resultInt <> 0 then failwith $"Expected 0 but got {resultInt}"
+"""
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Constants/Constants.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Constants/Constants.fs
index fd1d8440aef..b61a9043e5f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Constants/Constants.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Constants/Constants.fs
@@ -40,3 +40,20 @@ module Constants =
             (Error 636, Line 22, Col 9, Line 22, Col 15, "Units-of-measure are only supported on float, float32, decimal, and integer types.")
             (Error 636, Line 23, Col 9, Line 23, Col 15, "Units-of-measure are only supported on float, float32, decimal, and integer types.")
         ]
+
+    // https://github.com/dotnet/fsharp/issues/6929
+    [<Fact>]
+    let ``Issue 6929 - Literal bindings preserve units of measure`` () =
+        FSharp
+            """
+[<Measure>] type rad
+
+[<Literal>]
+let pi = 3.14<rad>
+
+let a = pi
+
+let f (x: float<rad>) = x
+let _ = f a
+            """
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
index c560008da0c..9e04bc75dfc 100644
--- a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
@@ -113,3 +113,101 @@ ignore ["1" .. "42"]
         |> shouldFail
         |> withSingleDiagnostic
             (Error 1, Line 2, Col 9, Line 2, Col 12, "The type 'string' does not support the operator 'op_Range'")
+
+    // https://github.com/dotnet/fsharp/issues/6648
+    [<Fact>]
+    let ``Issue 6648 - DU of DUs with inline static members should compile`` () =
+        FSharp
+            """
+type SomeUnion1<'T> =
+    | Case1A of 'T
+    | Case1B of 'T
+    static member inline (-) (a, b) =
+        match a, b with
+        | Case1A x, Case1A y -> Case1A(x - y)
+        | Case1B x, Case1B y -> Case1B(x - y)
+        | _ -> failwith "mismatch"
+
+type SomeUnion2<'T> =
+    | Case2A of 'T
+    | Case2B of 'T
+    static member inline (-) (a, b) =
+        match a, b with
+        | Case2A x, Case2A y -> Case2A(x - y)
+        | Case2B x, Case2B y -> Case2B(x - y)
+        | _ -> failwith "mismatch"
+
+type UnionOfUnions<'T> =
+    | ParentCase1 of SomeUnion1<'T>
+    | ParentCase2 of SomeUnion2<'T>
+    static member inline (-) (a, b) =
+        match a, b with
+        | ParentCase1 x, ParentCase1 y -> x - y |> ParentCase1
+        | ParentCase2 x, ParentCase2 y -> x - y |> ParentCase2
+        | _ -> failwith "mismatch"
+            """
+        |> asLibrary
+        |> typecheck
+        |> shouldSucceed
+
+    // https://github.com/dotnet/fsharp/issues/9878
+    [<Fact>]
+    let ``Issue 9878 - SRTP with phantom type parameter should compile`` () =
+        FSharp
+            """
+type DuCaseName<'T> =
+    static member ToCaseName<'t, 'u>(value: 't) = failwith "delayed resolution"
+    static member ToCaseName(value: 'T) =
+        match FSharp.Reflection.FSharpValue.GetUnionFields(value, typeof<'T>) with case, _ -> case.Name
+    static member inline Invoke(value: 'a) =
+        let inline call (other: ^M, value: ^I) = ((^M or ^I) : (static member ToCaseName: ^I -> string) value)
+        call (Unchecked.defaultof<DuCaseName<_>>, value)
+            """
+        |> asLibrary
+        |> typecheck
+        |> shouldSucceed
+
+    // https://github.com/dotnet/fsharp/issues/9382
+    [<Fact>]
+    let ``Issue 9382 - SRTP stress test with matrix inverse should compile`` () =
+        FSharp
+            """
+type Matrix<'a> =
+    { m11: 'a; m12: 'a; m13: 'a
+      m21: 'a; m22: 'a; m23: 'a
+      m31: 'a; m32: 'a; m33: 'a }
+
+    static member inline (/) (m, s) =
+        { m11 = m.m11 / s; m12 = m.m12 / s; m13 = m.m13 / s
+          m21 = m.m21 / s; m22 = m.m22 / s; m23 = m.m23 / s
+          m31 = m.m31 / s; m32 = m.m32 / s; m33 = m.m33 / s }
+
+    static member inline (*) (a, b) =
+        { m11 = a.m11 * b.m11 + a.m12 * b.m21 + a.m13 * b.m31
+          m12 = a.m11 * b.m12 + a.m12 * b.m22 + a.m13 * b.m32
+          m13 = a.m11 * b.m13 + a.m12 * b.m23 + a.m13 * b.m33
+          m21 = a.m21 * b.m11 + a.m22 * b.m21 + a.m23 * b.m31
+          m22 = a.m21 * b.m12 + a.m22 * b.m22 + a.m23 * b.m32
+          m23 = a.m21 * b.m13 + a.m22 * b.m23 + a.m23 * b.m33
+          m31 = a.m31 * b.m11 + a.m32 * b.m21 + a.m33 * b.m31
+          m32 = a.m31 * b.m12 + a.m32 * b.m22 + a.m33 * b.m32
+          m33 = a.m31 * b.m13 + a.m32 * b.m23 + a.m33 * b.m33 }
+
+let inline determinant m =
+    m.m11 * m.m22 * m.m33 + m.m12 * m.m23 * m.m31 + m.m13 * m.m21 * m.m32
+    - m.m13 * m.m22 * m.m31 - m.m12 * m.m21 * m.m33 - m.m11 * m.m23 * m.m32
+
+let inline inverse m =
+    { m11 = m.m22 * m.m33 - m.m32 * m.m23
+      m12 = m.m13 * m.m32 - m.m12 * m.m33
+      m13 = m.m12 * m.m23 - m.m13 * m.m22
+      m21 = m.m23 * m.m31 - m.m21 * m.m33
+      m22 = m.m11 * m.m33 - m.m13 * m.m31
+      m23 = m.m21 * m.m13 - m.m11 * m.m23
+      m31 = m.m21 * m.m32 - m.m31 * m.m22
+      m32 = m.m31 * m.m12 - m.m11 * m.m32
+      m33 = m.m11 * m.m22 - m.m21 * m.m12 }
+    / (determinant m)
+            """
+        |> typecheck
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Closures.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Closures.fs
index 1f8fb7840fe..898656a55d0 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Closures.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Closures.fs
@@ -365,3 +365,62 @@ let main _ =
         |> shouldSucceed
         |> ignore
 
+    // https://github.com/dotnet/fsharp/issues/3660
+    [<Fact>]
+    let ``Issue_3660_ArrayOfFunctionsInvocationCorrectness`` () =
+        let source =
+            """
+module Test
+
+let runAll (fArr: (int -> int) array) x =
+    let mutable n = 0
+
+    for i = 0 to fArr.Length - 1 do
+        n <- n + fArr[i] x
+
+    n
+
+[<EntryPoint>]
+let main _ =
+    let fns = [| (fun x -> x + 1); (fun x -> x * 2); (fun x -> x - 3) |]
+    let result = runAll fns 10
+    if result <> (11 + 20 + 7) then failwithf "Expected 38, got %d" result
+    printfn "SUCCESS"
+    0
+"""
+
+        FSharp source
+        |> asExe
+        |> compile
+        |> shouldSucceed
+        |> run
+        |> shouldSucceed
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/3660
+    // Verify that indexed array function invocation does not emit closure classes
+    [<Fact>]
+    let ``Issue_3660_NoClosureClassForIndexedArrayInvocation`` () =
+        let source =
+            """
+module Test
+
+let runAll (fArr: (int -> int) array) x =
+    let mutable n = 0
+
+    for i = 0 to fArr.Length - 1 do
+        n <- n + fArr[i] x
+
+    n
+"""
+
+        FSharp source
+        |> asLibrary
+        |> withOptimize
+        |> compile
+        |> shouldSucceed
+        |> verifyILNotPresent [
+            "extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc"
+        ]
+        |> ignore
+
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_TypeDefs.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_TypeDefs.fs
new file mode 100644
index 00000000000..0fe36c5bf33
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_TypeDefs.fs
@@ -0,0 +1,289 @@
+// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
+
+namespace EmittedIL
+
+open Xunit
+open FSharp.Test
+open FSharp.Test.Compiler
+
+module CodeGenRegressions_TypeDefs =
+
+    // https://github.com/dotnet/fsharp/issues/16565
+    [<Fact>]
+    let ``Issue_16565_DefaultAugmentationFalseDuplicateEntry`` () =
+        let source = """
+module Test
+
+open System
+
+[<DefaultAugmentation(false)>]
+type Option<'T> =
+    | Some of Value: 'T
+    | None
+
+    member x.Value =
+        match x with
+        | Some x -> x
+        | None -> raise (new InvalidOperationException("Option.Value"))
+
+    static member None : Option<'T> = None
+
+and 'T option = Option<'T>
+
+let v = Option.Some 42
+printfn "Value: %d" v.Value
+let n = Option<int>.None
+printfn "None created successfully"
+"""
+        FSharp source
+        |> asExe
+        |> compile
+        |> shouldSucceed
+        |> run
+        |> shouldSucceed
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/14321
+    [<Fact>]
+    let ``Issue_14321_DuAndIWSAMNames`` () =
+        let source = """
+module Test
+
+#nowarn "3535"  // IWSAM warning
+
+type EngineError<'e> =
+    static abstract Overheated : 'e
+    static abstract LowOil : 'e
+
+type CarError =
+    | Overheated
+    | LowOil
+    | DeviceNotPaired
+
+    interface EngineError<CarError> with
+        static member Overheated = Overheated
+        static member LowOil = LowOil
+"""
+        FSharp source
+        |> asLibrary
+        |> compile
+        |> shouldSucceed
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/14321
+    // Runtime test: type must load without "duplicate entry in method table"
+    [<Fact>]
+    let ``Issue_14321_DuAndIWSAMNames_Runtime`` () =
+        let source = """
+module Test
+
+#nowarn "3535"
+
+type EngineError<'e> =
+    static abstract Overheated : 'e
+    static abstract LowOil : 'e
+
+type CarError =
+    | Overheated
+    | LowOil
+    | DeviceNotPaired
+
+    interface EngineError<CarError> with
+        static member Overheated = Overheated
+        static member LowOil = LowOil
+
+[<EntryPoint>]
+let main _ =
+    let err = CarError.Overheated
+    match err with
+    | Overheated -> printfn "Got Overheated"
+    | LowOil -> printfn "Got LowOil"
+    | DeviceNotPaired -> printfn "Got DeviceNotPaired"
+    0
+"""
+        FSharp source
+        |> asExe
+        |> compile
+        |> shouldSucceed
+        |> run
+        |> shouldSucceed
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/5834
+    [<Fact>]
+    let ``Issue_5834_EventSpecialname`` () =
+        let source = """
+module Test
+
+open System
+open System.Reflection
+
+type IAbstract1 =
+    [<CLIEvent>]
+    abstract member Event : IEvent<EventHandler, EventArgs>
+
+type IAbstract2 =
+    [<CLIEvent>]
+    abstract member Event : IDelegateEvent<EventHandler>
+
+[<AbstractClass>]
+type Abstract3() =
+    [<CLIEvent>]
+    abstract member Event : IDelegateEvent<EventHandler>
+
+type Concrete1() =
+    let event = new Event<EventHandler, EventArgs>()
+    [<CLIEvent>]
+    member this.Event = event.Publish
+
+type Concrete2() =
+    [<CLIEvent>]
+    member this.Event = { new IDelegateEvent<EventHandler> with
+                              member this.AddHandler _ = ()
+                              member this.RemoveHandler _ = () }
+
+type ConcreteWithObsolete() =
+    let evt = new Event<EventHandler, EventArgs>()
+    [<Obsolete("deprecated")>]
+    [<CLIEvent>]
+    member this.MyEvent = evt.Publish
+
+[<EntryPoint>]
+let main _ =
+    let mutable failures = 0
+    let check (t: Type) =
+        t.GetMethods(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.DeclaredOnly)
+        |> Array.filter (fun m -> m.Name.Contains("Event"))
+        |> Array.iter (fun m ->
+            if not m.IsSpecialName then
+                printfn "FAIL: %s.%s missing specialname" t.Name m.Name
+                failures <- failures + 1)
+
+    check typeof<IAbstract1>
+    check typeof<IAbstract2>
+    check typeof<Abstract3>
+    check typeof<Concrete1>
+    check typeof<Concrete2>
+    check typeof<ConcreteWithObsolete>
+
+    if failures > 0 then
+        failwithf "BUG: %d event accessors missing specialname" failures
+    printfn "SUCCESS: All event accessors have specialname"
+    0
+"""
+        FSharp source
+        |> asExe
+        |> compile
+        |> shouldSucceed
+        |> run
+        |> shouldSucceed
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/5834
+    // IL verification: abstract event accessors must have specialname flag
+    [<Fact>]
+    let ``Issue_5834_EventSpecialname_IL`` () =
+        let source = """
+module Test
+
+open System
+
+type IAbstract1 =
+    [<CLIEvent>]
+    abstract member Event : IEvent<EventHandler, EventArgs>
+
+[<AbstractClass>]
+type Abstract2() =
+    [<CLIEvent>]
+    abstract member Event : IDelegateEvent<EventHandler>
+"""
+        FSharp source
+        |> asLibrary
+        |> compile
+        |> shouldSucceed
+        |> verifyIL [
+            // Interface abstract event accessors have specialname
+            """.method public hidebysig specialname abstract virtual instance void  add_Event(class [runtime]System.EventHandler A_1) cil managed"""
+
+            """.method public hidebysig specialname abstract virtual instance void  remove_Event(class [runtime]System.EventHandler A_1) cil managed"""
+
+            // IAbstract1 event references its accessors
+            """.addon instance void Test/IAbstract1::add_Event(class [runtime]System.EventHandler)"""
+            """.removeon instance void Test/IAbstract1::remove_Event(class [runtime]System.EventHandler)"""
+
+            // Abstract2 event also references its specialname accessors
+            """.addon instance void Test/Abstract2::add_Event(class [runtime]System.EventHandler)"""
+            """.removeon instance void Test/Abstract2::remove_Event(class [runtime]System.EventHandler)"""
+        ]
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/14321
+    // IL verification: DU case properties and IWSAM implementations coexist without duplicates
+    [<Fact>]
+    let ``Issue_14321_DuAndIWSAMNames_IL`` () =
+        let source = """
+module Test
+
+#nowarn "3535"
+
+type EngineError<'e> =
+    static abstract Overheated : 'e
+    static abstract LowOil : 'e
+
+type CarError =
+    | Overheated
+    | LowOil
+    | DeviceNotPaired
+
+    interface EngineError<CarError> with
+        static member Overheated = Overheated
+        static member LowOil = LowOil
+"""
+        FSharp source
+        |> asLibrary
+        |> compile
+        |> shouldSucceed
+        |> verifyIL [
+            // DU case property getter exists on CarError
+            """.method public static class Test/CarError get_Overheated() cil managed"""
+
+            // Explicit IWSAM implementation uses mangled name
+            """.method public hidebysig specialname static class Test/CarError  'Test.EngineError<Test.CarError>.get_Overheated'() cil managed"""
+
+            // Explicit IWSAM for LowOil also present
+            """.method public hidebysig specialname static class Test/CarError  'Test.EngineError<Test.CarError>.get_LowOil'() cil managed"""
+        ]
+        |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/16565
+    // IL verification: DefaultAugmentation(false) produces no duplicate method table entries
+    [<Fact>]
+    let ``Issue_16565_DefaultAugmentationFalseDuplicateEntry_IL`` () =
+        let source = """
+module Test
+
+[<DefaultAugmentation(false)>]
+type MyOption<'T> =
+    | Some of Value: 'T
+    | None
+
+    member x.Value =
+        match x with
+        | Some x -> x
+        | None -> failwith "no value"
+
+    static member None : MyOption<'T> = None
+"""
+        FSharp source
+        |> asLibrary
+        |> compile
+        |> shouldSucceed
+        |> verifyIL [
+            // The user-defined get_Value method exists on the main type with specialname
+            """.method public hidebysig specialname instance !T  get_Value() cil managed"""
+
+            // The static get_None method exists
+            """.method public static class Test/MyOption`1<!T> get_None() cil managed"""
+        ]
+        |> ignore
+
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs
new file mode 100644
index 00000000000..7310f83dbd1
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs
@@ -0,0 +1,129 @@
+module ErrorMessages.DiagnosticRegressionTests
+
+open Xunit
+open FSharp.Test.Compiler
+
+// https://github.com/dotnet/fsharp/issues/6715
+[<Fact>]
+let ``Issue 6715 - land is a valid identifier after ML compat removal`` () =
+    FSharp
+        """
+let land = 3
+let lor = 4
+let lxor = 5
+let lsl = 6
+let lsr = 7
+let asr = 8
+let sum = land + lor + lxor + lsl + lsr + asr
+        """
+    |> asLibrary
+    |> typecheck
+    |> shouldSucceed
+
+// https://github.com/dotnet/fsharp/issues/15655
+[<Fact>]
+let ``Issue 15655 - error codes 999 and 3217 are distinct`` () =
+    // Verify that notAFunctionButMaybeIndexerErrorCode (3217) is distinct from packageManagerError (999)
+    // by triggering a "not a function but maybe indexer" error
+    FSharp
+        """
+let d = System.Collections.Generic.Dictionary<string,int>()
+let v = d ["key"]
+        """
+    |> typecheck
+    |> shouldFail
+    |> withErrorCode 3217
+
+    
+// https://github.com/dotnet/fsharp/issues/13697
+[<Fact>]
+let ``Issue 13697 - typeof with out of scope type in attribute should report FS0039`` () =
+    FSharp
+        """
+type FooAttribute(t:System.Type) = inherit System.Attribute()
+[<Foo(typeof<OutOfScopeType>)>]
+type Vehicle() = class end
+        """
+    |> typecheck
+    |> shouldFail
+    |> withDiagnostics
+        [ (Error 39, Line 3, Col 14, Line 3, Col 28, "The type 'OutOfScopeType' is not defined.")
+          (Error 267, Line 3, Col 7, Line 3, Col 29, "This is not a valid constant expression or custom attribute value") ]
+
+// https://github.com/dotnet/fsharp/issues/10043
+[<Fact>]
+let ``Issue 10043 - backtick in type annotation should not report unexpected keyword`` () =
+    FSharp
+        """
+let i:float`1 = 3.0
+        """
+    |> typecheck
+    |> shouldFail
+    |> withDiagnostics
+        [ (Error 3563, Line 2, Col 12, Line 2, Col 13, "This is not a valid identifier")
+          (Error 10, Line 2, Col 13, Line 2, Col 14, "Unexpected integer literal in binding. Expected '=' or other token.") ]
+
+// https://github.com/dotnet/fsharp/issues/10043
+[<Fact>]
+let ``Issue 10043 - at sign in type annotation should report infix operator`` () =
+    FSharp
+        """
+let i:float@1 = 3.0
+        """
+    |> typecheck
+    |> shouldFail
+    |> withDiagnostics
+        [ (Error 615, Line 2, Col 12, Line 2, Col 13, "Unexpected infix operator in type expression") ]
+
+// https://github.com/dotnet/fsharp/issues/10043
+[<Fact>]
+let ``Issue 10043 - bang in type annotation should report reserved identifier`` () =
+    FSharp
+        """
+let i:float!1 = 3.0
+        """
+    |> typecheck
+    |> shouldFail
+    |> withDiagnostics
+        [ (Error 1141, Line 2, Col 7, Line 2, Col 13, "Identifiers followed by '!' are reserved for future use")
+          (Error 10, Line 2, Col 13, Line 2, Col 14, "Unexpected integer literal in binding. Expected '=' or other token.") ]
+
+// https://github.com/dotnet/fsharp/issues/7177
+[<Fact>]
+let ``Issue 7177 - never matched warning FS0026 is emitted when active pattern precedes wildcard rules`` () =
+    FSharp """
+let (|AP|_|) (x: obj) = Some()
+
+let _ =
+    match obj() with
+    | AP _ -> ()
+    | _ -> ()
+    | _ -> ()
+    """
+    |> asLibrary
+    |> typecheck
+    |> shouldFail
+    |> withWarningCode 26
+
+// https://github.com/dotnet/fsharp/issues/16410
+[<Fact>]
+let ``Issue 16410 - no spurious FS3570 warning with KeyValue active pattern`` () =
+    FSharp
+        """
+open System.Collections.Generic
+
+module Map =
+    let update empty k f m =
+        match Map.tryFind k m with
+        | Some v -> Map.add k (f v) m
+        | None -> Map.add k (f empty) m
+
+let invert (dict: IDictionary<'k,#seq<'k>>): Map<'k,Set<'k>> =
+    (Map.empty, dict)
+    ||> Seq.fold (fun res (KeyValue (k, ks)) ->
+            (res, ks)
+            ||> Seq.fold (fun res vk -> res |> Map.update Set.empty vk _.Add(k))
+        )
+        """
+    |> typecheck
+    |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs
index 942ab64dfcd..b5cf1bcbccb 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs
@@ -176,6 +176,63 @@ while x < 1 do
         |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 9,
                                  "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")
 
+    // https://github.com/dotnet/fsharp/issues/5735
+    [<Fact>]
+    let ``Warn On Last Expression In For Loop - int``() =
+        FSharp """
+module ClassLibrary17
+
+for i in 1 .. 10 do
+    printfn ""
+    printfn "" |> ignore
+    123
+        """
+        |> typecheck
+        |> shouldFail
+        |> withSingleDiagnostic (Warning 20, Line 7, Col 5, Line 7, Col 8,
+                                 "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")
+
+    // https://github.com/dotnet/fsharp/issues/5735
+    [<Fact>]
+    let ``Warn On Last Expression In For Loop - string``() =
+        FSharp """
+for i in 1 .. 10 do
+    printfn ""
+    "hello"
+        """
+        |> typecheck
+        |> shouldFail
+        |> withSingleDiagnostic (Warning 20, Line 4, Col 5, Line 4, Col 12,
+                                 "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")
+
+    // https://github.com/dotnet/fsharp/issues/5735
+    [<Fact>]
+    let ``Warn On Last Expression In Integer For Loop``() =
+        FSharp """
+for i = 1 to 10 do
+    printfn ""
+    42
+        """
+        |> typecheck
+        |> shouldFail
+        |> withSingleDiagnostic (Warning 20, Line 4, Col 5, Line 4, Col 7,
+                                 "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")
+
+    // https://github.com/dotnet/fsharp/issues/5735
+    [<Fact>]
+    let ``Warn On Last Expression In While Loop - non-bool``() =
+        FSharp """
+let mutable x = 0
+while x < 1 do
+    printfn "unneeded"
+    x <- x + 1
+    123
+        """
+        |> typecheck
+        |> shouldFail
+        |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 8,
+                                 "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")
+
     [<Fact>]
     let ``Warn If Possible Property Setter``() =
         FSharp """
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 193ac623645..f5d1048408e 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -280,6 +280,7 @@
     <Compile Include="EmittedIL\Nullness\NullnessMetadata.fs" />
     <Compile Include="EmittedIL\FixedBindings\FixedBindings.fs" />
     <Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_Observations.fs" />
+    <Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_TypeDefs.fs" />
     <Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_Signatures.fs" />
     <Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_Closures.fs" />
     <Compile Include="ErrorMessages\TypedInterpolatedStringsTests.fs" />
@@ -300,6 +301,7 @@
     <Compile Include="ErrorMessages\MissingElseBranch.fs" />
     <Compile Include="ErrorMessages\MissingExpressionTests.fs" />
     <Compile Include="ErrorMessages\ModuleTests.fs" />
+    <Compile Include="ErrorMessages\DiagnosticRegressionTests.fs" />
     <Compile Include="ErrorMessages\NameResolutionTests.fs" />
     <Compile Include="ErrorMessages\SuggestionsTests.fs" />
     <Compile Include="ErrorMessages\TypeMismatchTests.fs" />
diff --git a/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs b/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs
index 97d0dcd865b..74298498dbb 100644
--- a/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs
+++ b/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs
@@ -1997,9 +1997,13 @@ if toEnd <> [| 3; 4; 5 |] then exit 1
 let name = "World"
 let count = 42
 let greeting = $"Hello, {name}! Count: {count}"
+printfn "%s" greeting
 if greeting <> "Hello, World! Count: 42" then exit 1
 
+System.Globalization.CultureInfo.CurrentCulture <- System.Globalization.CultureInfo.InvariantCulture
+
 let formatted = $"Pi is approximately {System.Math.PI:F2}"
+printfn "%s" formatted
 if not (formatted.Contains("3.14")) then exit 1
 ()
 """
diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs
index 6499cbf9259..00a5781553f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs
@@ -114,3 +114,112 @@ Holder.Label <- "nope"
         fsLib
         |> compile
         |> shouldFail
+
+    // https://github.com/dotnet/fsharp/issues/13519
+    [<FSharp.Test.FactForNETCOREAPP>]
+    let ``Issue 13519 - C# method with optional parameters can be called from F# without specifying defaults`` () =
+        let csLib =
+            CSharp
+                """
+using System;
+
+namespace CSharpLib
+{
+    public class MyClass
+    {
+        public string DoSomething(string required, string optional1 = "default1", string optional2 = "default2")
+        {
+            return required + "|" + optional1 + "|" + optional2;
+        }
+    }
+}
+            """
+            |> withName "CSharpOptionalParams"
+
+        let fsApp =
+            FSharp
+                """
+module TestApp
+
+open CSharpLib
+
+[<EntryPoint>]
+let main _ =
+    let c = MyClass()
+    let result = c.DoSomething("hello")
+    if result <> "hello|default1|default2" then
+        failwithf "Expected 'hello|default1|default2' but got '%s'" result
+    let result2 = c.DoSomething("hello", "custom1")
+    if result2 <> "hello|custom1|default2" then
+        failwithf "Expected 'hello|custom1|default2' but got '%s'" result2
+    0
+                """
+            |> withReferences [ csLib ]
+
+        fsApp
+        |> asExe
+        |> compileExeAndRun
+        |> shouldSucceed
+
+    // https://github.com/dotnet/fsharp/issues/13519
+    // Specifically testing the intersection of optional parameters and ParamArray
+    // as identified by Don Syme: https://github.com/dotnet/fsharp/issues/13519#issuecomment-1253808416
+    [<FSharp.Test.FactForNETCOREAPP>]
+    let ``Issue 13519 - C# method with optional parameters and ParamArray can be called from F# without specifying defaults`` () =
+        let csLib =
+            CSharp
+                """
+using System;
+
+namespace CSharpParamArrayLib
+{
+    public class Assertions
+    {
+        public string BeEquivalentTo(string expected, string because = "", params object[] becauseArgs)
+        {
+            string formatted = because;
+            if (becauseArgs != null && becauseArgs.Length > 0)
+            {
+                formatted = string.Format(because, becauseArgs);
+            }
+            return expected + "|" + formatted + "|" + becauseArgs.Length;
+        }
+    }
+}
+                """
+            |> withName "CSharpParamArrayLib"
+
+        let fsApp =
+            FSharp
+                """
+module TestParamArrayApp
+
+open CSharpParamArrayLib
+
+[<EntryPoint>]
+let main _ =
+    let a = Assertions()
+
+    // Call with only the required argument - omitting both optional and params
+    let result1 = a.BeEquivalentTo("test")
+    if result1 <> "test||0" then
+        failwithf "Test 1 failed: Expected 'test||0' but got '%s'" result1
+
+    // Call with required + optional, omitting params
+    let result2 = a.BeEquivalentTo("test", "because {0}")
+    if result2 <> "test|because {0}|0" then
+        failwithf "Test 2 failed: Expected 'test|because {0}|0' but got '%s'" result2
+
+    // Call with all arguments including params values
+    let result3 = a.BeEquivalentTo("test", "because {0}", "reason")
+    if result3 <> "test|because reason|1" then
+        failwithf "Test 3 failed: Expected 'test|because reason|1' but got '%s'" result3
+
+    0
+                """
+            |> withReferences [ csLib ]
+
+        fsApp
+        |> asExe
+        |> compileExeAndRun
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs
index b19ff83cf95..829b56eca14 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs
@@ -24,6 +24,28 @@ module ``Test Compiler Directives`` =
             |> shouldFail
             |> withSingleDiagnostic (Warning 213, Line 2, Col 1, Line 2, Col 10, "'' is not a valid assembly name")
 
+    // https://github.com/dotnet/fsharp/issues/3841
+    [<Fact>]
+    let ``Hash directive inside nested module produces indentation error`` () =
+        Fsx
+            """
+let x = 42
+
+module Nested =
+    let foo = 123
+
+#r "SomeAssembly"
+
+    let bar = 1
+
+let y = x
+            """
+        |> withLangVersion80
+        |> compile
+        |> shouldFail
+        |> withSingleDiagnostic
+            (Error 58, Line 11, Col 1, Line 11, Col 4, "Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (9:5). Try indenting this further.\nTo continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7.")
+
 module ``Test compiler directives in FSI`` =
     [<Fact>]
     let ``r# "" is invalid`` () =
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
index 378879bbfc3..13652e42ef3 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
@@ -2323,3 +2323,22 @@ let result = query { for x in data1 do join (y, name) in data2 on (x = y); selec
         |> shouldFail
         |> withSingleDiagnostic (Warning 1182, Line line1, Col col1, Line line2, Col col2, msg)
         |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/19456
+    [<Fact>]
+    let ``Issue 19456 - let bang nested in plain let binding inside task CE should raise FS0750`` () =
+        FSharp """
+open System.Threading.Tasks
+
+let y() =
+    task {
+        let a =
+            let! b = Task.FromResult([| "hello" |])
+            b
+        return a
+    }
+        """
+        |> asLibrary
+        |> typecheck
+        |> shouldFail
+        |> withErrorCode 750
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs
index fe2963643f3..5fe9d33a6a6 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs
@@ -187,3 +187,45 @@ if giveMeZ().IsX then failwith "Should not be X"
         """
         |> compileExeAndRun
         |> shouldSucceed
+
+    // https://github.com/dotnet/fsharp/issues/6750
+    [<Fact>]
+    let ``Mutually recursive DU values are fully initialized`` () =
+        Fsx """
+type A = A of B
+and B = B of A | C
+
+// Case 1: non-recursive values declared with let rec
+let rec a1 = B (A b1)
+and b1 = B (A c1)
+and c1 = C
+
+// Case 2: truly recursive values
+let rec a2 = A b2
+and b2 = B a2
+
+// Verify Case 1
+match a1 with
+| B (A (B (A C))) -> ()
+| _ -> failwithf "a1 was not fully initialized: %A" a1
+
+match b1 with
+| B (A C) -> ()
+| _ -> failwithf "b1 was not fully initialized: %A" b1
+
+match c1 with
+| C -> ()
+| _ -> failwithf "c1 was not fully initialized: %A" c1
+
+// Verify Case 2
+match a2 with
+| A (B a2ref) -> if not (obj.ReferenceEquals(a2ref, a2)) then failwithf "a2 inner ref is wrong: %A" a2
+| _ -> failwithf "a2 was not fully initialized: %A" a2
+
+match b2 with
+| B (A b2inner) ->
+    if not (obj.ReferenceEquals(b2inner, b2)) then failwithf "b2 inner ref is wrong: %A" b2
+| _ -> failwithf "b2 was not fully initialized: %A" b2
+        """
+        |> compileExeAndRun
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs
index 39396d06a71..3b7d1a2b3a5 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs
@@ -53,3 +53,32 @@ let f (start: DateTime) (stop: DateTime) (input: (DateTime * 'a) list) =
         |> compile
         |> shouldSucceed
         |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/14152
+    [<Fact>]
+    let ``Issue 14152 - nowarn directive before module declaration should compile`` () =
+        FSharp
+            """
+#nowarn "20"
+
+module XXX.MyModule
+
+let x = 15
+            """
+        |> asLibrary
+        |> typecheck
+        |> shouldSucceed
+
+    // https://github.com/dotnet/fsharp/issues/16007
+    [<Fact>]
+    let ``Issue 16007 - SRTP ctor constraint should not cause value restriction error`` () =
+        FSharp """
+type T() = class end
+let dosmth (a: T) = System.Console.WriteLine(a.ToString())
+let inline NEW () = (^a : (new : unit -> ^a) ())
+let x = NEW ()
+dosmth x
+        """
+        |> asLibrary
+        |> typecheck
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs
index f7d2ebb906c..4857f27704f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs
@@ -425,5 +425,44 @@ if (four [ ("", 10) ]).Result <> 6 then
         |> compileExeAndRun
         |> shouldSucceed
 
+    // https://github.com/dotnet/fsharp/issues/16154
+    // VerificationException still occurs on .NET Framework due to stricter IL verification;
+    // fixed on .NET Core where the upcast-to-obj in the task state machine is handled correctly.
+    [<FSharp.Test.FactForNETCOREAPP>]
+    let ``Issue 16154 - task CE with IQueryable filter functions should compile and run without VerificationException`` () =
+        FSharp """
+open System.Linq
+
+type Shape = {x: int; y: int}
 
+let returnFilter condition =
+    task {
+        if condition = "a" then
+            let filter1 : IQueryable<Shape> -> IQueryable<Shape> =
+                fun data -> data.Where(fun a -> a.x = 1)
+            return Some filter1
+        elif condition = "b" then
+            let filter2 : IQueryable<Shape> -> IQueryable<Shape> =
+                fun data -> data.Where(fun a -> a.y <> 2)
+            return Some filter2
+        else
+            return None
+    }
 
+let data = [{x = 1; y = 1}; {x = 2; y = 2}].AsQueryable()
+let result =
+    task {
+        let! f1 = returnFilter "a"
+        let! f2 = returnFilter "b"
+        match f1, f2 with
+        | Some filter1, Some filter2 ->
+            return data |> filter2 |> filter1 |> Seq.toList
+        | _ -> return []
+    } |> (fun t -> t.GetAwaiter().GetResult())
+
+if result.Length <> 1 then failwith $"unexpected result length {result.Length}"
+if result[0].x <> 1 then failwith $"unexpected result {result[0]}"
+        """
+        |> asExe
+        |> compileExeAndRun
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs
index 0b6e230a271..e0cfdff2ffd 100644
--- a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs
@@ -23,7 +23,7 @@ module ScriptRunner =
     let private getOrCreateEngine(args,version) sessionIsolation =
         match sessionIsolation with
         | ScriptSessionIsolation.Isolated ->
-            new FSharpScript(args, true, version)
+            getIsolatedSessionForEval args version
         | ScriptSessionIsolation.Shared ->
             getSessionForEval args version
 
diff --git a/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs b/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs
index dfded2c01df..ea7e3fbe312 100644
--- a/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs
@@ -93,6 +93,17 @@ module ``External FSI tests`` =
         |> runFsi
         |> shouldFail
 
+    // https://github.com/dotnet/fsharp/issues/12023
+    [<FSharp.Test.FactSkipOnSignedBuild>]
+    let ``Issue 12023 - FSI can load System.Drawing.Common via nuget reference``() =
+        Fsx """
+#r "nuget: System.Drawing.Common"
+open System.Drawing
+printfn "Assembly loaded: %s" (typeof<Color>.Assembly.GetName().Name)
+        """
+        |> runFsi
+        |> shouldSucceed
+
 
     [<Fact>]
     let ``Internals visible over a large number of submissions``() =
@@ -157,3 +168,17 @@ module MultiEmit =
         |> withStdOutContains ".NET:"
         |> withStdOutContains "OS:"
         |> ignore
+
+    // https://github.com/dotnet/fsharp/issues/14216
+    [<Fact>]
+    let ``Issue 14216 - No multiemit warning FS2303 when using DU in FSI`` () =
+        Fsx
+            """
+type T = U of unit
+let x = U()
+
+match x with
+| U v -> v
+"""
+        |> eval
+        |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs b/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs
index b6717ecd5ba..9a3279f7105 100644
--- a/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs
@@ -110,3 +110,18 @@ let ``typecheck-only flag prevents execution with #load``() =
         |> verifyNotInOutput "Domain.fsx output"
         |> verifyNotInOutput "A.fsx output"
         |> ignore)
+
+// https://github.com/dotnet/fsharp/issues/15070
+[<Fact>]
+let ``Issue 15070 - hash-load with dot-slash prefix does not produce FS1141`` () =
+    // Before the fix, #load "./path" produced FS1141 "Identifiers followed by '!' are reserved for future use"
+    // After the fix, the parser accepts "./path" and reports a file-not-found error instead.
+    withTempDirectory (fun tempDir ->
+        let mainContent = "#load \"./non-existent-subfolder/some-script.fsx\""
+        let mainPath = writeScript tempDir "main.fsx" mainContent
+
+        FsxFromPath mainPath
+        |> runFsi
+        |> shouldFail
+        |> withStdErrContains "Unable to find the file"
+        |> ignore)
diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/ModuleOrNamespaceTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/ModuleOrNamespaceTests.fs
index 062b8ba9166..f7575dc7d0f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Signatures/ModuleOrNamespaceTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Signatures/ModuleOrNamespaceTests.fs
@@ -215,3 +215,38 @@ namespace MyApp.Types
 
     type Meh =
       class end"""
+
+// https://github.com/dotnet/fsharp/issues/12067
+[<Fact>]
+let ``External FSharp namespace type prefix is preserved in signature`` () =
+    let externalLib =
+        FSharp
+            """
+namespace FSharp.Control
+
+type AsyncSeq<'t> =
+    member this.Length: int = 0
+
+    static member BufferByCount: count: int -> source: AsyncSeq<'t> -> AsyncSeq<'t array> =
+        failwith "todo"
+"""
+
+    FSharp
+        """
+namespace FSharp.MyStuff
+
+module Library =
+    open FSharp.Control
+
+    let batch (s: AsyncSeq<'t>) = s
+"""
+    |> withReferences [ externalLib ]
+    |> printSignatures
+    |> prependNewline
+    |> assertEqualIgnoreLineEnding
+        """
+namespace FSharp.MyStuff
+
+  module Library =
+
+    val batch: s: FSharp.Control.AsyncSeq<'t> -> FSharp.Control.AsyncSeq<'t>"""
diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs
index e534b5d325b..d01eb764bc8 100644
--- a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs
@@ -342,4 +342,102 @@ type GenericType<'X> with
 
     one |> withAdditionalSourceFiles [ two; three ]
     |> compile
-    |> verifyILContains [ ".Print<ActualType>" ]
\ No newline at end of file
+    |> verifyILContains [ ".Print<ActualType>" ]
+
+// https://github.com/dotnet/fsharp/issues/14310
+[<Fact>]
+let ``Signature generation via --sig includes private field for struct type`` () =
+    let implSource =
+        """
+module StructPrivateField
+
+[<Struct; NoComparison; NoEquality>]
+type C =
+    [<DefaultValue>]
+    val mutable private goo : byte array
+    member this.P with set(x) = this.goo <- x
+"""
+
+    let sigSource =
+        """
+module StructPrivateField
+
+[<NoComparison; NoEquality; Struct>]
+type C =
+
+    [<DefaultValue>]
+    val mutable private goo: byte array
+
+    member P: byte array with set
+"""
+
+    Fsi sigSource
+    |> withAdditionalSourceFile (FsSource implSource)
+    |> withOptions [ "--warnaserror:64" ]
+    |> ignoreWarnings
+    |> compile
+    |> shouldSucceed
+    |> ignore
+
+// https://github.com/dotnet/fsharp/issues/14308
+[<Fact>]
+let ``Signature generation via --sig includes Sealed, AbstractClass, Interface and Class attributes`` () =
+    let implSource =
+        """
+module AttrTest
+
+[<Sealed>]
+type SealedClass() =
+    member _.X = 1
+
+[<AbstractClass>]
+type AbstractClass() =
+    abstract member Y : int
+
+[<Interface>]
+type IMyInterface =
+    abstract member Z : int
+
+[<Class>]
+type ExplicitClass() =
+    member _.W = 2
+"""
+
+    let sigSource =
+        """
+module AttrTest
+
+[<Sealed>]
+type SealedClass =
+
+    new: unit -> SealedClass
+
+    member X: int
+
+[<AbstractClass>]
+type AbstractClass =
+
+    new: unit -> AbstractClass
+
+    abstract Y: int
+
+[<Interface>]
+type IMyInterface =
+
+    abstract Z: int
+
+[<Class>]
+type ExplicitClass =
+
+    new: unit -> ExplicitClass
+
+    member W: int
+"""
+
+    Fsi sigSource
+    |> withAdditionalSourceFile (FsSource implSource)
+    |> withOptions [ "--warnaserror:64" ]
+    |> ignoreWarnings
+    |> compile
+    |> shouldSucceed
+    |> ignore
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.Service.Tests/Checker.fs b/tests/FSharp.Compiler.Service.Tests/Checker.fs
index 5d16f87783d..22dcf2ad502 100644
--- a/tests/FSharp.Compiler.Service.Tests/Checker.fs
+++ b/tests/FSharp.Compiler.Service.Tests/Checker.fs
@@ -162,6 +162,11 @@ module Checker =
         let parseResults, checkResults = getParseAndCheckResults context.Source
         checkResults.GetCodeCompletionSuggestions(context, parseResults, options)
 
+    let getCompletionInfoWithCompilerAndCompletionOptions (compilerOptions: string array) (completionOptions: FSharpCodeCompletionOptions) (markedSource: string) =
+        let context = getCompletionContext markedSource
+        let parseResults, checkResults = getParseAndCheckResultsWithOptions compilerOptions context.Source
+        checkResults.GetCodeCompletionSuggestions(context, parseResults, completionOptions)
+
     let getCompletionInfo markedSource =
         getCompletionInfoWithOptions FSharpCodeCompletionOptions.Default markedSource
 
diff --git a/tests/FSharp.Compiler.Service.Tests/Common.fs b/tests/FSharp.Compiler.Service.Tests/Common.fs
index 5c548c43eae..7fad5ff15c5 100644
--- a/tests/FSharp.Compiler.Service.Tests/Common.fs
+++ b/tests/FSharp.Compiler.Service.Tests/Common.fs
@@ -311,11 +311,11 @@ let attribsOfSymbol (symbol: FSharpSymbol) =
             if v.IsDispatchSlot then yield "slot"
             if v.IsModuleValueOrMember && not v.IsMember then yield "val"
             if v.IsMember then yield "member"
-            if v.IsProperty then yield "prop"
+            if v.IsProperty && not v.IsEvent then yield "prop"
+            if v.IsEvent then yield "event"
             if v.IsExtensionMember then yield "extmem"
             if v.IsPropertyGetterMethod then yield "getter"
             if v.IsPropertySetterMethod then yield "setter"
-            if v.IsEvent then yield "event"
             if v.EventForFSharpProperty.IsSome then yield "clievent"
             if v.IsEventAddMethod then yield "add"
             if v.IsEventRemoveMethod then yield "remove"
diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
index 43ee08b4ee3..e229a6f2b34 100644
--- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
+++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
@@ -691,6 +691,86 @@ exception E
 try () with E{caret}
 """
 
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``Event - Instance 01`` () =
+            assertItem "Ev" """
+type T() =
+    [<System.Obsolete; CLIEvent>]
+    member _.Ev = Event<System.EventHandler, _>().Publish
+
+T().{caret}
+"""
+
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``Event - Static 01`` () =
+            assertItem "Ev" """
+type T() =
+    [<System.Obsolete; CLIEvent>]
+    static member Ev = Event<System.EventHandler, _>().Publish
+
+T.{caret}
+"""
+
+        /// Helper to assert completion with a reference to the CSharp_Analysis assembly
+        let private assertCSharpInteropItem name source =
+            let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll"
+            let compilerOptions = [| $"-r:{csharpAssembly}" |]
+            [allowObsoleteOptions; disallowObsoleteOptions]
+            |> List.iter (fun completionOptions ->
+                let contains = completionOptions.SuggestObsoleteSymbols
+                let info = Checker.getCompletionInfoWithCompilerAndCompletionOptions compilerOptions completionOptions source
+                assertItemsWithNames contains [name] info
+            )
+
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``CSharp - Obsolete field is hidden`` () =
+            assertCSharpInteropItem "ObsoleteField" """
+open FSharp.Compiler.Service.Tests
+ObsoleteMembersClass.{caret}
+"""
+
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``CSharp - Obsolete method is hidden`` () =
+            assertCSharpInteropItem "ObsoleteMethod" """
+open FSharp.Compiler.Service.Tests
+ObsoleteMembersClass.{caret}
+"""
+
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``CSharp - Obsolete property is hidden`` () =
+            assertCSharpInteropItem "ObsoleteProperty" """
+open FSharp.Compiler.Service.Tests
+ObsoleteMembersClass.{caret}
+"""
+
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``CSharp - Obsolete event is hidden`` () =
+            assertCSharpInteropItem "ObsoleteEvent" """
+open FSharp.Compiler.Service.Tests
+ObsoleteMembersClass.{caret}
+"""
+
+        // https://github.com/dotnet/fsharp/issues/13512
+        [<Fact>]
+        let ``CSharp - Non-obsolete members are always shown`` () =
+            let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll"
+            let compilerOptions = [| $"-r:{csharpAssembly}" |]
+            let source = """
+open FSharp.Compiler.Service.Tests
+ObsoleteMembersClass.{caret}
+"""
+            [allowObsoleteOptions; disallowObsoleteOptions]
+            |> List.iter (fun completionOptions ->
+                let info = Checker.getCompletionInfoWithCompilerAndCompletionOptions compilerOptions completionOptions source
+                assertItemsWithNames true ["NonObsoleteField"; "NonObsoleteMethod"; "NonObsoleteProperty"; "NonObsoleteEvent"] info
+            )
+
 
     module PatternNameSuggestions =
         let private suggestPatternNames = { FSharpCodeCompletionOptions.Default with SuggestPatternNames = true }
diff --git a/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs b/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs
index 4505f898776..cd494f7e659 100644
--- a/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs
+++ b/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs
@@ -991,7 +991,7 @@ let ``Test project3 all symbols in signature`` () =
         ("member set_InterfacePropertySet", ["slot"; "member"; "setter"]);
         ("property InterfacePropertySet", ["slot"; "member"; "prop"]);
         ("property InterfaceProperty", ["slot"; "member"; "prop"]);
-        ("property InterfaceEvent", ["slot"; "member"; "prop"; "clievent"]);
+        ("event InterfaceEvent", ["slot"; "member"; "event"; "clievent"]);
         ("CFoo", ["class"]);
         ("member .ctor", ["member"; "ctor"]);
         ("member AbstractClassMethod", ["slot"; "member"]);
@@ -1002,7 +1002,7 @@ let ``Test project3 all symbols in signature`` () =
         ("member set_AbstractClassPropertySet", ["slot"; "member"; "setter"]);
         ("property AbstractClassPropertySet", ["slot"; "member"; "prop"]);
         ("property AbstractClassProperty", ["slot"; "member"; "prop"]);
-        ("property AbstractClassEvent", ["slot"; "member"; "prop"; "clievent"]);
+        ("event AbstractClassEvent", ["slot"; "member"; "event"; "clievent"]);
         ("CBaseFoo", ["class"]); ("member .ctor", ["member"; "ctor"]);
         ("member BaseClassMethod", ["slot"; "member"]);
         ("member BaseClassMethod", ["member"; "overridemem"]);
@@ -1020,8 +1020,8 @@ let ``Test project3 all symbols in signature`` () =
         ("property BaseClassPropertySet", ["slot"; "member"; "prop"]);
         ("property BaseClassProperty", ["member"; "prop"; "overridemem"]);
         ("property BaseClassProperty", ["slot"; "member"; "prop"]);
-        ("property BaseClassEvent", ["member"; "prop"; "overridemem"]);
-        ("property BaseClassEvent", ["slot"; "member"; "prop"]);
+        ("event BaseClassEvent", ["member"; "event"; "overridemem"]);
+        ("event BaseClassEvent", ["slot"; "member"; "event"]);
         ("IFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]);
         ("member InterfaceMethod", ["member"; "overridemem"; "intfmem"]);
         ("member add_InterfaceEvent", ["member"; "overridemem"; "intfmem"]);
@@ -1038,7 +1038,7 @@ let ``Test project3 all symbols in signature`` () =
         ("member set_AbstractClassPropertySet", ["member"; "setter"; "overridemem"]);
         ("property AbstractClassPropertySet", ["member"; "prop"; "overridemem"]);
         ("property AbstractClassProperty", ["member"; "prop"; "overridemem"]);
-        ("property AbstractClassEvent", ["member"; "prop"; "clievent"; "overridemem"]);
+        ("event AbstractClassEvent", ["member"; "event"; "clievent"; "overridemem"]);
         ("CBaseFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]);
         ("member BaseClassMethod", ["member"; "overridemem"]);
         ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]);
@@ -1048,7 +1048,7 @@ let ``Test project3 all symbols in signature`` () =
         ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]);
         ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]);
         ("property BaseClassProperty", ["member"; "prop"; "overridemem"]);
-        ("property BaseClassEvent", ["member"; "prop"; "clievent"; "overridemem"])]
+        ("event BaseClassEvent", ["member"; "event"; "clievent"; "overridemem"])]
         |> List.iter (fun x ->
             if results |> List.exists (fun y -> x = y) |> not then
                 failwithf "%A does not exist in the collection." x
@@ -1122,10 +1122,10 @@ let ``Test project3 all uses of all signature symbols`` () =
            ("file1", ((61, 20), (61, 37)), ["override"], ["slot"; "member"; "prop"]);
            ("file1", ((76, 23), (76, 44)), [], ["slot"; "member"; "prop"]);
            ("file1", ((34, 20), (34, 37)), ["override"], ["slot"; "member"; "prop"])]);
-         ("property InterfaceEvent",
-          [("file1", ((8, 13), (8, 27)), ["defn"], ["slot"; "member"; "prop"; "clievent"]);
-           ("file1", ((65, 20), (65, 34)), ["override"], ["slot"; "member"; "prop"; "clievent"]);
-           ("file1", ((38, 20), (38, 34)), ["override"], ["slot"; "member"; "prop"; "clievent"])]);
+         ("event InterfaceEvent",
+          [("file1", ((8, 13), (8, 27)), ["defn"], ["slot"; "member"; "event"; "clievent"]);
+           ("file1", ((65, 20), (65, 34)), ["override"], ["slot"; "member"; "event"; "clievent"]);
+           ("file1", ((38, 20), (38, 34)), ["override"], ["slot"; "member"; "event"; "clievent"])]);
          ("CFoo",
           [("file1", ((11, 5), (11, 9)), ["defn"], ["class"]);
            ("file1", ((41, 12), (41, 16)), ["type"], ["class"]);
@@ -1170,10 +1170,10 @@ let ``Test project3 all uses of all signature symbols`` () =
           [("file1", ((12, 13), (12, 34)), ["defn"], ["slot"; "member"; "prop"]);
            ("file1", ((70, 22), (70, 43)), ["override"], ["slot"; "member"; "prop"]);
            ("file1", ((43, 18), (43, 39)), ["override"], ["slot"; "member"; "prop"])]);
-         ("property AbstractClassEvent",
-          [("file1", ((16, 13), (16, 31)), ["defn"], ["slot"; "member"; "prop"; "clievent"]);
-           ("file1", ((74, 22), (74, 40)), ["override"], ["slot"; "member"; "prop"; "clievent"]);
-           ("file1", ((47, 18), (47, 36)), ["override"], ["slot"; "member"; "prop"; "clievent"])]);
+         ("event AbstractClassEvent",
+          [("file1", ((16, 13), (16, 31)), ["defn"], ["slot"; "member"; "event"; "clievent"]);
+           ("file1", ((74, 22), (74, 40)), ["override"], ["slot"; "member"; "event"; "clievent"]);
+           ("file1", ((47, 18), (47, 36)), ["override"], ["slot"; "member"; "event"; "clievent"])]);
          ("CBaseFoo",
           [("file1", ((18, 5), (18, 13)), ["defn"], ["class"]);
            ("file1", ((50, 12), (50, 20)), ["type"], ["class"]);
@@ -1230,12 +1230,12 @@ let ``Test project3 all uses of all signature symbols`` () =
           [("file1", ((20, 13), (20, 30)), ["defn"], ["slot"; "member"; "prop"]);
            ("file1", ((25, 15), (25, 32)), ["override"], ["slot"; "member"; "prop"]);
            ("file1", ((52, 18), (52, 35)), ["override"], ["slot"; "member"; "prop"])]);
-         ("property BaseClassEvent",
-          [("file1", ((29, 15), (29, 29)), ["defn"], ["member"; "prop"; "overridemem"])]);
-         ("property BaseClassEvent",
-          [("file1", ((24, 13), (24, 27)), ["defn"], ["slot"; "member"; "prop"]);
-           ("file1", ((29, 15), (29, 29)), ["override"], ["slot"; "member"; "prop"]);
-           ("file1", ((56, 18), (56, 32)), ["override"], ["slot"; "member"; "prop"])]);
+         ("event BaseClassEvent",
+          [("file1", ((29, 15), (29, 29)), ["defn"], ["member"; "event"; "overridemem"])]);
+         ("event BaseClassEvent",
+          [("file1", ((24, 13), (24, 27)), ["defn"], ["slot"; "member"; "event"]);
+           ("file1", ((29, 15), (29, 29)), ["override"], ["slot"; "member"; "event"]);
+           ("file1", ((56, 18), (56, 32)), ["override"], ["slot"; "member"; "event"])]);
          ("IFooImpl", [("file1", ((31, 5), (31, 13)), ["defn"], ["class"])]);
          ("member .ctor", [("file1", ((31, 5), (31, 13)), ["defn"], ["member"; "ctor"])]);
          ("member InterfaceMethod",
@@ -1268,8 +1268,8 @@ let ``Test project3 all uses of all signature symbols`` () =
           [("file1", ((44, 18), (44, 42)), ["defn"], ["member"; "prop"; "overridemem"])]);
          ("property AbstractClassProperty",
           [("file1", ((43, 18), (43, 39)), ["defn"], ["member"; "prop"; "overridemem"])]);
-         ("property AbstractClassEvent",
-          [("file1", ((47, 18), (47, 36)), ["defn"], ["member"; "prop"; "clievent"; "overridemem"])]);
+         ("event AbstractClassEvent",
+          [("file1", ((47, 18), (47, 36)), ["defn"], ["member"; "event"; "clievent"; "overridemem"])]);
          ("CBaseFooImpl", [("file1", ((49, 5), (49, 17)), ["defn"], ["class"])]);
          ("member .ctor", [("file1", ((49, 5), (49, 17)), ["defn"], ["member"; "ctor"])]);
          ("member BaseClassMethod",
@@ -1288,8 +1288,8 @@ let ``Test project3 all uses of all signature symbols`` () =
           [("file1", ((53, 18), (53, 38)), ["defn"], ["member"; "prop"; "overridemem"])]);
          ("property BaseClassProperty",
           [("file1", ((52, 18), (52, 35)), ["defn"], ["member"; "prop"; "overridemem"])]);
-         ("property BaseClassEvent",
-          [("file1", ((56, 18), (56, 32)), ["defn"], ["member"; "prop"; "clievent"; "overridemem"])])]
+         ("event BaseClassEvent",
+          [("file1", ((56, 18), (56, 32)), ["defn"], ["member"; "event"; "clievent"; "overridemem"])])]
     set allUsesOfAllSymbols - set expected |> shouldEqual Set.empty
     set expected - set allUsesOfAllSymbols |> shouldEqual Set.empty
     (set expected = set allUsesOfAllSymbols) |> shouldEqual true
@@ -4065,13 +4065,13 @@ let ``Test project28 all symbols in signature`` () =
         ("FSharpMemberOrFunctionOrValue", "TestEvent2", "M:M.XmlDocSigTest.TestEvent2(System.Object)");
         ("FSharpMemberOrFunctionOrValue", "add_AnEvent", "M:M.XmlDocSigTest.add_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})");
         ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty");
-        ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent");
+        ("FSharpMemberOrFunctionOrValue", "AnEvent", "E:M.XmlDocSigTest.AnEvent");
         ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent");
         ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty");
         ("FSharpMemberOrFunctionOrValue", "remove_AnEvent", "M:M.XmlDocSigTest.remove_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})");
         ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty");
         ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent");
-        ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent");
+        ("FSharpMemberOrFunctionOrValue", "AnEvent", "E:M.XmlDocSigTest.AnEvent");
         ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty");
         ("FSharpField", "event1", "P:M.XmlDocSigTest.event1");
         ("FSharpField", "event2", "P:M.XmlDocSigTest.event2");
diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs
index 67da15c91e0..3f4d4fcdbd9 100644
--- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs
+++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs
@@ -842,6 +842,38 @@ type T() =
         let param = mfv.CurriedParameterGroups[0][0]
         param.Name.Value |> shouldEqual "x"
 
+    // https://github.com/dotnet/fsharp/issues/16056
+    [<Fact>]
+    let ``Auto property DeclarationLocation points to property name, not get accessor`` () =
+        let _, checkResults =
+            getParseAndCheckResults """
+module Module
+
+type T() =
+    member val Prop : int = 1 with get, set
+
+let _ = T().Prop
+"""
+        let propUsageOpt =
+            checkResults.GetAllUsesOfAllSymbolsInFile()
+            |> Seq.tryFind (fun su ->
+                match su.Symbol with
+                | :? FSharpMemberOrFunctionOrValue as mfv ->
+                    mfv.IsProperty && mfv.LogicalName = "Prop" && not su.IsFromDefinition
+                | _ -> false)
+
+        match propUsageOpt with
+        | None -> failwith "Expected to find Prop usage symbol"
+        | Some symbolUse ->
+            match symbolUse.Symbol with
+            | :? FSharpMemberOrFunctionOrValue as mfv ->
+                let loc = mfv.DeclarationLocation
+                // "    member val Prop" - 'P' in 'Prop' starts at column 15 (0-indexed)
+                // Should NOT point to `get` accessor (which is at column 35)
+                Assert.Equal(5, loc.StartLine)
+                Assert.Equal(15, loc.StartColumn)
+            | _ -> failwith "Expected FSharpMemberOrFunctionOrValue"
+
 module GetValSignatureText =
     let private assertSignature (expected:string) source (lineNumber, column, line, identifier) =
         let _, checkResults = getParseAndCheckResults source
@@ -1286,6 +1318,19 @@ type T() =
             )
 
         Assert.False hasPropertySymbols
+        
+    [<Fact>]
+    let ``CLIEvent is recognized as event`` () =
+        let symbolUse = Checker.getSymbolUse """
+type T() =
+    [<CLIEvent>]
+    member this.Ev{caret}ent = Event<int>().Publish
+"""
+        match symbolUse.Symbol with
+        | :? FSharpMemberOrFunctionOrValue as mfv ->
+            Assert.True mfv.IsEvent
+            Assert.StartsWith("E:", mfv.XmlDocSig)
+        | _ -> failwith "Expected FSharpMemberOrFunctionOrValue"
 
     [<Fact>]
     let ``CLIEvent 01 - Synthetic range`` () =
@@ -1358,6 +1403,59 @@ let test = System.DateTimeKind.Utc
                 failwith "Expected metadata text, got None"
         | _ -> failwith "Expected FSharpEntity symbol"
 
+module IsByRef =
+    // https://github.com/dotnet/fsharp/issues/3532
+    [<Fact>]
+    let ``FSharpEntity.IsByRef is true for byref return type of address-of operator`` () =
+        let _, checkResults =
+            getParseAndCheckResults
+                """
+let mutable x = 1
+let y = &x
+"""
+
+        let symbolUse = findSymbolUseByName "op_AddressOf" checkResults
+
+        match symbolUse.Symbol with
+        | :? FSharpMemberOrFunctionOrValue as mfv ->
+            let retTy = mfv.ReturnParameter.Type
+
+            Assert.True(
+                retTy.HasTypeDefinition,
+                $"Expected return type of op_AddressOf to have a TypeDefinition, got: %A{retTy}"
+            )
+
+            Assert.True(
+                retTy.TypeDefinition.IsByRef,
+                $"Expected return type TypeDefinition.IsByRef = true for op_AddressOf, got entity: %s{retTy.TypeDefinition.DisplayName}"
+            )
+        | symbol -> failwith $"Expected FSharpMemberOrFunctionOrValue but got %A{symbol}"
+
+    [<Fact>]
+    let ``FSharpEntity.IsByRef is true for byref type used explicitly`` () =
+        let _, checkResults =
+            getParseAndCheckResults
+                """
+let f (x: byref<int>) = x <- 42
+"""
+
+        let symbolUse = findSymbolUseByName "f" checkResults
+
+        match symbolUse.Symbol with
+        | :? FSharpMemberOrFunctionOrValue as mfv ->
+            let paramTy = mfv.CurriedParameterGroups.[0].[0].Type
+
+            Assert.True(
+                paramTy.HasTypeDefinition,
+                $"Expected byref parameter type to have a TypeDefinition, got: %A{paramTy}"
+            )
+
+            Assert.True(
+                paramTy.TypeDefinition.IsByRef,
+                $"Expected parameter TypeDefinition.IsByRef = true for byref<int>, got entity: %s{paramTy.TypeDefinition.DisplayName}"
+            )
+        | symbol -> failwith $"Expected FSharpMemberOrFunctionOrValue but got %A{symbol}"
+        
 module OperatorsWithDots =
     // https://github.com/dotnet/fsharp/issues/14057
     [<Fact>]
@@ -1404,4 +1502,4 @@ let result = 1 -.- 2
         let range = usageSymbols.[0].Range
         let rangeLength = range.EndColumn - range.StartColumn
 
-        Assert.Equal(3, rangeLength)
\ No newline at end of file
+        Assert.Equal(3, rangeLength)
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs
index b0532b8929f..837574aefdc 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs
@@ -304,6 +304,10 @@ type ArrayModule2() =
         // len = 0
         CheckThrowsArgumentException(fun() -> Array.maxBy funcInt (Array.empty<int>) |> ignore)
         
+        // returns first maximal element
+        let max = Array.maxBy fst [|1, "a"; 2, "b"; 3, "c"; 2, "d"; 3, "e"; 1, "f" |]
+        if snd max <> "c" then Assert.Fail()
+        
         ()
 
     [<Fact>]
@@ -348,6 +352,10 @@ type ArrayModule2() =
         // len = 0
         CheckThrowsArgumentException(fun () -> Array.minBy funcInt (Array.empty<int>) |> ignore)
         
+        // returns first minimal element
+        let min = Array.minBy fst [|3, "a"; 2, "b"; 1, "c"; 2, "d"; 1, "e"; 3, "f" |]
+        if snd min <> "c" then Assert.Fail()
+        
         ()
         
 
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs
index 3a27d4e7d2a..ab3b0365d69 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs
@@ -291,6 +291,10 @@ type ListModule02() =
         // empty List    
         CheckThrowsArgumentException ( fun() -> List.maxBy (fun () -> 1) List.empty )
 
+        // returns first maximal element
+        let max = List.maxBy fst [1, "a"; 2, "b"; 3, "c"; 2, "d"; 3, "e"; 1, "f" ]
+        if snd max <> "c" then Assert.Fail()
+        
         ()
 
     [<Fact>]
@@ -324,6 +328,10 @@ type ListModule02() =
         let funcEpt () = 1
         CheckThrowsArgumentException ( fun() -> List.minBy funcEpt List.empty)
        
+        // returns first minimal element
+        let min = List.minBy fst [ 3, "a"; 2, "b"; 1, "c"; 2, "d"; 1, "e"; 3, "f" ]
+        if snd min <> "c" then Assert.Fail()
+        
         ()
 
     [<Fact>]
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs
index db3b8a3adcc..9ac290935fe 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs
@@ -969,6 +969,10 @@ type SeqModule2() =
         let nullSeq:seq<'a> = null 
         CheckThrowsArgumentNullException (fun () ->Seq.maxBy funcInt nullSeq |> ignore)
         
+        // returns first maximal element
+        let max = Seq.maxBy fst (seq { 1, "a"; 2, "b"; 3, "c"; 2, "d"; 3, "e"; 1, "f" })
+        if snd max <> "c" then Assert.Fail()
+        
         ()
         
     [<Fact>]
@@ -991,6 +995,10 @@ type SeqModule2() =
         let nullSeq:seq<'a> = null 
         CheckThrowsArgumentNullException (fun () ->Seq.minBy funcInt nullSeq |> ignore)
         
+        // returns first minimal element
+        let min = Seq.minBy fst (seq { 3, "a"; 2, "b"; 1, "c"; 2, "d"; 1, "e"; 3, "f" })
+        if snd min <> "c" then Assert.Fail()
+        
         ()
         
           
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs
index 1e872a07a3f..3bf50a19fb3 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs
@@ -172,7 +172,8 @@ type AsyncType() =
         let t : Task<unit> = Async.StartAsTask(a, cancellationToken = cts.Token)
 
         // Wait for the async body to actually start executing before checking timing.
-        Assert.True(asyncStarted.Wait(5000), "Async body did not start within 5 seconds")
+        // Use a generous timeout to avoid flaky failures on loaded CI machines where the thread pool may be saturated.
+        Assert.True(asyncStarted.Wait(30_000), "Async body did not start within 30 seconds")
 
         // Should not finish, we don't eagerly mark the task done just because it's been signaled to cancel.
         try
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index afbe687012e..af1f36ca80f 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -1133,13 +1133,11 @@ module rec Compiler =
         let outputWritten, errorsWritten = capture.OutText, capture.ErrorText
         processScriptResults fs result outputWritten errorsWritten
 
-    let scriptingShim = Path.Combine(__SOURCE_DIRECTORY__,"ScriptingShims.fsx")
     let private evalScriptFromDisk (fs: FSharpCompilationSource) (script:FSharpScript) : CompilationResult =
 
         let fileNames =
             (fs.Source :: fs.AdditionalSources)
             |> List.map (fun x -> x.GetSourceFileName)
-            |> List.insertAt 0 scriptingShim
             |> List.map (sprintf " @\"%s\"")
             |> String.Concat
 
@@ -1158,13 +1156,21 @@ module rec Compiler =
 
     let internal sessionCache = 
         Collections.Concurrent.ConcurrentDictionary<Set<string> * LangVersion, FSharpScript>()
+
+    let internal createSessionWithShadowedExit args version =
+        let script = new FSharpScript(additionalArgs=args,quiet=true,langVersion=version)
+        script.ApplyExitShadowing()
+        script
+
+    let getIsolatedSessionForEval args version =
+        createSessionWithShadowedExit args version
     
     let getSessionForEval args version =
         let key = Set args, version
         match sessionCache.TryGetValue(key) with
         | true, script -> script
         | _ -> 
-            let script = new FSharpScript(additionalArgs=args,quiet=true,langVersion=version)
+            let script = createSessionWithShadowedExit args version
             sessionCache.TryAdd(key, script) |> ignore
             script
 
diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs
index 760a8278d04..d09896563e5 100644
--- a/tests/FSharp.Test.Utilities/CompilerAssert.fs
+++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs
@@ -22,6 +22,7 @@ open FSharp.Compiler.BuildGraph
 open System.Runtime.Loader
 #endif
 open FSharp.Test.Utilities
+open FSharp.Test.ScriptHelpers
 open Microsoft.CodeAnalysis
 open Microsoft.CodeAnalysis.CSharp
 open Xunit
@@ -1006,41 +1007,25 @@ Updated automatically, please check diffs in your pull request, changes must be
         // Save CurrentUICulture and GraphNode.culture to restore after FSI session
         // FSI may change these via --preferreduilang option, and the change persists
         // in the static GraphNode.culture which affects async computations in other tests
-        let originalUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture
-        let originalGraphNodeCulture = GraphNode.culture
-        
+        let originalUICulture = CultureInfo.CurrentUICulture
+        let originalGraphNodeCulture = GraphNode.culture     
         try
-            // Initialize output and input streams
-            use inStream = new StringReader("")
             use outStream = new StringWriter()
             use errStream = new StringWriter()
+            use script = new FSharpScript(additionalArgs = Array.append [| "--noninteractive" |] options, quiet = false, outWriter = outStream, errWriter = errStream)
+            script.ApplyExitShadowing()
+            let result, errors = script.Eval(source)
 
-            // Build command line arguments & start FSI session
-            let argv = [| "C:\\fsi.exe" |]
-#if NETCOREAPP
-            let args = Array.append argv [|"--noninteractive"; "--targetprofile:netcore"|]
-#else
-            let args = Array.append argv [|"--noninteractive"; "--targetprofile:mscorlib"|]
-#endif
-            let allArgs = Array.append args options
-
-            let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
-            use fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream, collectible = true)
-
-            let ch, errors = fsiSession.EvalInteractionNonThrowing source
-
-            let errorMessages = ResizeArray()
-            errors
-            |> Seq.iter (fun error -> errorMessages.Add(error.Message))
+            let errorMessages = ResizeArray(errors |> Seq.map _.Message)
 
-            match ch with
-            | Choice2Of2 ex -> errorMessages.Add(ex.Message)
+            match result with
+            | Result.Error ex -> errorMessages.Add(ex.Message)
             | _ -> ()
 
             errorMessages, string outStream, string errStream
         finally
             // Restore CurrentUICulture and GraphNode.culture to prevent culture leaking between tests
-            System.Threading.Thread.CurrentThread.CurrentUICulture <- originalUICulture
+            CultureInfo.CurrentUICulture <- originalUICulture
             GraphNode.culture <- originalGraphNodeCulture
 
     static member RunScriptWithOptions options (source: string) (expectedErrorMessages: string list) =
diff --git a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj
index fde44ceb83d..cb5f54ad381 100644
--- a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj
+++ b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj
@@ -25,16 +25,15 @@
     <Compile Include="..\scripts\scriptlib.fsx">
       <Link>scriptlib.fsx</Link>
     </Compile>
-    <None Include="ScriptingShims.fsx" />
     <Compile Include="TestConsole.fs" />
     <Compile Include="TestFramework.fs" />
     <Compile Include="ILChecker.fs" />
     <Compile Include="Utilities.fs" />
     <Compile Include="VSInstallDiscovery.fs" />
+    <Compile Include="ScriptHelpers.fs" />
     <Compile Include="CompilerAssert.fs" />
     <Compile Include="ProjectGeneration.fs" />
     <Compile Include="Assert.fs" />
-    <Compile Include="ScriptHelpers.fs" />
     <Compile Include="Compiler.fs" />
     <Compile Include="ILVerifierModule.fs" />
     <Compile Include="DataAttributeBase.fs" />
diff --git a/tests/FSharp.Test.Utilities/ScriptHelpers.fs b/tests/FSharp.Test.Utilities/ScriptHelpers.fs
index a0c5b178488..cb2956ab8ac 100644
--- a/tests/FSharp.Test.Utilities/ScriptHelpers.fs
+++ b/tests/FSharp.Test.Utilities/ScriptHelpers.fs
@@ -19,7 +19,7 @@ type LangVersion =
     | Preview
     | Latest
 
-type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion) =
+type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion, ?outWriter: IO.TextWriter, ?errWriter: IO.TextWriter) =
 
     let additionalArgs = defaultArg additionalArgs [||]
     let quiet = defaultArg quiet true
@@ -44,13 +44,23 @@ type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVer
 
     let argv = Array.append baseArgs additionalArgs
 
-    let fsi = FsiEvaluationSession.Create (config, argv, TextReader.Null, stdout, stderr)
+    let outWriter = defaultArg outWriter stdout
+    let errWriter = defaultArg errWriter stderr
+    let fsi = FsiEvaluationSession.Create (config, argv, TextReader.Null, outWriter, errWriter)
 
     member _.ValueBound = fsi.ValueBound
 
     member _.Fsi = fsi
 
-    member this.Eval(code: string, ?cancellationToken: CancellationToken, ?desiredCulture: Globalization.CultureInfo) =
+    member _.ApplyExitShadowing() =
+        fsi.EvalInteraction """
+let exit (code:int) = 
+    if code = 0 then 
+        () 
+    else failwith $"Script called function 'exit' with code={code}."
+        """
+
+    member _.Eval(code: string, ?cancellationToken: CancellationToken, ?desiredCulture: Globalization.CultureInfo) =
         let originalCulture = Thread.CurrentThread.CurrentCulture
         let originalUICulture = Thread.CurrentThread.CurrentUICulture
         Thread.CurrentThread.CurrentCulture <- Option.defaultValue Globalization.CultureInfo.InvariantCulture desiredCulture
diff --git a/tests/FSharp.Test.Utilities/ScriptingShims.fsx b/tests/FSharp.Test.Utilities/ScriptingShims.fsx
deleted file mode 100644
index be9ce9142c5..00000000000
--- a/tests/FSharp.Test.Utilities/ScriptingShims.fsx
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace global
-
-[<AutoOpen>]
-module GlobalShims = 
-    let exit (code:int) = 
-        if code = 0 then 
-            () 
-        else failwith $"Script called function 'exit' with code={code}."
diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs
index dcb64909ad2..2348b09df8e 100644
--- a/tests/FSharp.Test.Utilities/TestFramework.fs
+++ b/tests/FSharp.Test.Utilities/TestFramework.fs
@@ -60,8 +60,6 @@ let rec copyDirectory (sourceDir: string) (destinationDir: string) (recursive: b
 [<RequireQualifiedAccess>]
 module Commands =
 
-    let gate = obj()
-
     // Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever
     // returns exit code, stdio and stderr as string arrays
     let executeProcess pathToExe arguments workingDir =
diff --git a/tests/fsharp/single-test.fs b/tests/fsharp/single-test.fs
index 41f6e032609..e8d26711979 100644
--- a/tests/fsharp/single-test.fs
+++ b/tests/fsharp/single-test.fs
@@ -9,8 +9,6 @@ open FSharp.Compiler.IO
 
 let testConfig = testConfig __SOURCE_DIRECTORY__
 
-let log = printfn
-
 type Permutation =
 #if NETCOREAPP
     | FSC_NETCORE of optimized: bool * buildOnly: bool
diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs
index e834af94aea..330ffe93590 100644
--- a/tests/fsharp/tests.fs
+++ b/tests/fsharp/tests.fs
@@ -27,8 +27,6 @@ let FSI = FSI_NETFX
 #endif
 // ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^
 
-let log = printfn
-
 module CoreTests =
 
 
diff --git a/tests/service/data/CSharp_Analysis/CSharpClass.cs b/tests/service/data/CSharp_Analysis/CSharpClass.cs
index a8131651b50..e8afc869dc2 100644
--- a/tests/service/data/CSharp_Analysis/CSharpClass.cs
+++ b/tests/service/data/CSharp_Analysis/CSharpClass.cs
@@ -155,4 +155,25 @@ public class DummyClass
         {
         }
     }
+
+    /// <summary>
+    /// Class with obsolete members for testing completion filtering (issue #13512).
+    /// </summary>
+    public class ObsoleteMembersClass
+    {
+        [Obsolete("Field is obsolete")] public static readonly int ObsoleteField = 1;
+
+        [Obsolete("Method is obsolete")]
+        public static void ObsoleteMethod()
+        {
+        }
+
+        [Obsolete("Property is obsolete")] public static int ObsoleteProperty => 1;
+        [Obsolete("Event is obsolete")] public static event EventHandler ObsoleteEvent;
+
+        public static readonly int NonObsoleteField = 2;
+        public static void NonObsoleteMethod() { }
+        public static int NonObsoleteProperty => 2;
+        public static event EventHandler NonObsoleteEvent;
+    }
 }
