RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/dotnet-maui-github-copilot-instructions ↔ dotnet-maui-github-instructions-sandbox-instructions

Comparison

A · Copilot instructions · dotnet/mauiB · Copilot instructions · dotnet/maui
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections036600%
Commands11894%
Section tags64250%

What each file covers

Sections

0 shared · 36 only in A · 60 only in B
  • − GitHub Copilot Development Environment Instructions
  • − Code Review Instructions
  • − Repository Overview
  • − Key Technologies
  • − Development Environment Setup
  • − Platform-Specific Requirements
  • − Project Structure
  • − Important Directories
  • − Platform-Specific Code Organization
  • − Platform-Specific File Extensions
  • − Sample Projects
  • − Development Workflow
  • − Testing
  • − CI Pipelines (Azure DevOps)
  • − Investigating CI Failures
  • − Gradle / Maven Dependency Failures (CFSClean)
  • − Code Formatting
  • − Contribution Guidelines
  • − Handling Existing PRs for Assigned Issues
  • − Auto-Generated Files (Never Commit)
  • − PublicAPI.Unshipped.txt File Management
  • − Branching
  • − Git Workflow (Copilot CLI Rules)
  • − Create a feature branch (NEVER work directly on main)
  • − Make commits normally
  • − Push to remote (for new branches)
  • − For subsequent pushes on the same branch
  • − Check out the PR branch directly (do NOT create a new branch off it)
  • − Make fixes and commit to the PR branch
  • − Documentation
  • − Opening PRs
  • − Custom Agents and Skills
  • − Skills vs Agents
  • − Available Custom Agents
  • − Reusable Skills
  • − Using Custom Agents
  • + Sandbox Testing Guide
  • + When This Applies
  • + 🚨 CRITICAL VALIDATION RULES - READ FIRST
  • + What You NEVER Do (Absolute Rules)
  • + What You ALWAYS Do (Mandatory Steps)
  • + Rule 1: NEVER ASSUME TEST COMPLETION
  • + Rule 2: ALWAYS VALIDATE TEST OUTPUT
  • + Rule 3: VALIDATE DEVICE LOGS FOR EXPECTED BEHAVIOR
  • + Rule 4: SYSTEMATIC VALIDATION CHECKLIST
  • + Step 1: Check for errors/exceptions FIRST
  • + Step 2: Verify expected test actions (MOST IMPORTANT - proves test actually ran)
  • + Step 3: Verify test completion marker
  • + Step 4: Verify device logs show expected behavior
  • + Step 5: Check screenshots were saved (if test captures them)
  • + Step 6: Check exit code
  • + 🚨 WARNING: "Test Completed Successfully" ≠ Test Actually Worked
  • + Example of False Success
  • + Check the logs:
  • + Result: 20+ lines of "no such element" errors
  • + The test looked for "InstructionLabel" which doesn't exist in MainPage
  • + Appium never found ANY elements
  • + Test script just gave up and exited with code 0
  • + NO ACTUAL TESTING WAS PERFORMED
  • + How to Detect False Success
  • + Look for actual test actions in output
  • + Purpose
  • + When to Use Sandbox Testing
  • + When NOT to Use Sandbox
  • + Distinction: Code Review vs. Functional Testing
  • + 🚨 Critical Requirements for Android Testing
  • + Core Workflow
  • + Step 1: Understand Issue (DO NOT Checkout PR Unless Instructed)
  • + ONLY if user explicitly asks to test a PR:
  • + Step 2: Create Test Scenario in Sandbox
  • + Step 3: Test WITH PR Fix
  • + How the Template Works
  • + Copy the template
  • + OPTIONAL: Add automated test logic in the TEST LOGIC section
  • + If you don't add test logic, it just verifies launch and exits
  • + Run the script
  • + 🚨 CRITICAL: BuildAndRunSandbox.ps1 Script - ONLY Way to Deploy Sandbox
  • + Script Location
  • + Basic Usage
  • + Android
  • + iOS (auto-detects device)
  • + iOS with specific device
  • + What the Script Does Automatically
  • + Requirements Before Running
  • + 📝 Note for User
  • + 1. Revert the PR fix files
  • + 2. Rerun test - bug should appear
  • + 3. Restore fix
  • + 4. Rerun test - bug should be gone
  • + 🔄 Iterative Testing Workflow (MANDATORY PROCESS)
  • + The Required Loop
  • + ❌ What NOT To Do
  • + ✅ Correct Iteration Example
  • + 1. Check what went wrong
  • + 2. Check what DOES exist in MainPage
  • + 3. Fix MainPage: Add AutomationIds

Commands

1 shared · 18 only in A · 9 only in B
  • − dotnet format Microsoft.Maui.sln --no-restore --exclude Templates/src --exclude-diagnostics CA1822
  • − git checkout -b feature/issue-12345
  • − git add .
  • − git commit -m "Fix: Description of the change"
  • − git push -u origin feature/issue-12345
  • − git push
  • − gh pr checkout 12345
  • − dotnet cake
  • − dotnet --version
  • − gh pr checks
  • − dotnet-public-maven
  • − dotnet/android#10738
  • − dotnet format analyzers
  • − git fetch origin
  • − git for-each-ref --sort=-version:refname --count=1 --format='%(refname:lstrip=3)' refs/remotes/origin/net*.0
  • − gh pr checkout
  • − dotnet test
  • − dotnet-dnceng@dotnet-arcade-skills
  • + gh pr checkout <PR_NUMBER>
  • + git checkout main -- [list specific fix files from PR]
  • + git checkout HEAD -- [fix files]
  • + git checkout -- src/Controls/samples/Controls.Sample.Sandbox/
  • + git checkout main
  • + dotnet build
  • + dotnet run
  • + git checkout main -- [fix files]
  • + dotnet build/run
  •   dotnet tool restore

Section tags

6 shared · 4 only in A · 2 only in B
  • − setup
  • − lint-format
  • − architecture
  • − docs
  • + build
  • + deployment
  •   test
  •   code-style
  •   testing-strategy
  •   git-pr
  •   do-not
  •   agent-behaviour

Line diff

+708 added−267 removed112 unchanged13.7% identical
dotnet/maui · .github/copilot-instructions.md
@@ −1 @@
1---
2description: "Guidance for GitHub Copilot when working on the .NET MAUI repository."
 
3---
4 
5# GitHub Copilot Development Environment Instructions
6 
7This document provides specific guidance for GitHub Copilot when working on the .NET MAUI repository. It serves as context for understanding the project structure, development workflow, and best practices.
8 
9## Code Review Instructions
10 
11When performing a code review on PRs that change functional code, run the pr-finalize skill to verify that the PR title and description accurately match the actual implementation. This ensures proper documentation and helps maintain high-quality commit messages.
 
 
 
 
 
12 
13## Repository Overview
14 
15**.NET MAUI** is a cross-platform framework for creating mobile and desktop applications with C# and XAML. This repository contains the core framework code that enables development for Android, iOS, iPadOS, macOS, and Windows from a single shared codebase.
16 
17### Key Technologies
18 
19- **.NET SDK** - Version is **ALWAYS** defined in `global.json` at repository root
20 - **main branch**: Latest stable .NET version
21 - **Feature branches**: Each `netN.0` branch targets the .NET N SDK. By convention, the highest `netN.0` branch is the current development branch for new features and API changes.
22- **Cake build system** for compilation and packaging (`dotnet cake`)
23- **MSBuild** with custom build tasks (must build `Microsoft.Maui.BuildTasks.slnf` first)
24- **Testing frameworks**:
25 - **xUnit** - Unit tests (`*.UnitTests.csproj`)
26 - **NUnit** - UI tests (`TestCases.Shared.Tests`)
27 - **Appium WebDriver** - UI test automation
28 
29## Development Environment Setup
30 
31This guidance assumes:
32- Repository is already cloned and tools are restored (`dotnet tool restore` completed)
33- Build tasks are compiled (`Microsoft.Maui.BuildTasks.slnf` built successfully)
34- Correct .NET SDK version installed (verify with `dotnet --version` against `global.json`)
 
 
35 
36### Platform-Specific Requirements
 
 
 
 
37 
38- **Android**: OpenJDK 17 + Android SDK (install via `android` command after `dotnet tool restore`)
39- **iOS/macOS**: Xcode (current stable version)
40- **Windows**: Windows SDK
 
 
 
41 
42## Project Structure
 
 
 
43 
44### Important Directories
45- `src/Core/` - Core MAUI framework code
46- `src/Controls/` - UI controls and components
47- `src/Essentials/` - Platform APIs and essentials
48- `src/TestUtils/` - Testing utilities and infrastructure
49- `docs/` - Development documentation
50- `eng/` - Build engineering and tooling
51- `.github/` - GitHub workflows and configuration
52 
53### Platform-Specific Code Organization
54- **Android** specific code is inside folders labeled `Android`
55- **iOS** specific code is inside folders labeled `iOS`
56- **MacCatalyst** specific code is inside folders named `MacCatalyst`
57- **Windows** specific code is inside folders named `Windows`
58 
59### Platform-Specific File Extensions
 
60 
61Platform-specific files use naming conventions to control compilation:
 
62 
63**File extension patterns**:
64- `.windows.cs` - Windows TFM only
65- `.android.cs` - Android TFM only
66- `.ios.cs` - iOS and MacCatalyst TFMs (both)
67- `.maccatalyst.cs` - MacCatalyst TFM only (does NOT compile for iOS)
68 
69**Important**: Both `.ios.cs` and `.maccatalyst.cs` files compile for MacCatalyst. There is no precedence mechanism that excludes one when the other exists.
 
70 
71**Example**: If you have both `CollectionView.ios.cs` and `CollectionView.maccatalyst.cs`, both will compile for MacCatalyst builds. The `.maccatalyst.cs` file won't compile for iOS, but the `.ios.cs` file will compile for both iOS and MacCatalyst.
 
 
72 
73### Sample Projects
74 
75- `src/Controls/samples/Maui.Controls.Sample` - Full gallery sample with all controls and features
76- `src/Controls/samples/Maui.Controls.Sample.Sandbox` - Empty project for testing/reproduction
77- `src/Essentials/samples/Essentials.Sample` - Essentials API demonstrations (non-UI MAUI APIs)
78- `src/BlazorWebView/samples/` - BlazorWebView sample applications
79 
80## Development Workflow
81 
82### Testing
83 
84Major test projects:
85- **Core**: `src/Core/tests/UnitTests/Core.UnitTests.csproj`
86- **Essentials**: `src/Essentials/test/UnitTests/Essentials.UnitTests.csproj`
87- **Controls**: `src/Controls/tests/Core.UnitTests/Controls.Core.UnitTests.csproj`
88- **XAML**: `src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj`
89 
90Find all tests: `find . -name "*.UnitTests.csproj"`
 
 
 
 
91 
92### CI Pipelines (Azure DevOps)
93 
94When referencing or triggering CI pipelines, use these current pipeline names:
 
 
95 
96| Pipeline | Name | Purpose |
97|----------|------|---------|
98| Overall CI | `maui-pr` | Full PR validation build |
99| Device Tests | `maui-pr-devicetests` | Helix-based device tests |
100| UI Tests | `maui-pr-uitests` | Appium-based UI tests |
 
 
 
101 
102**⚠️ Old pipeline names** (e.g., `MAUI-UITests-public`, `MAUI-public`) are **outdated** and should NOT be used. Always use the names above.
 
 
 
 
103 
104### Investigating CI Failures
 
 
 
 
105 
106**🚨 ALWAYS use the `azdo-build-investigator` skill when investigating CI failures or assessing merge readiness.** Its instructions direct you to invoke the `ci-analysis` skill first for the core investigation workflow, then apply MAUI-specific corrections (correct pipeline names, XHarness quirks, binlog guidance).
107 
108Do NOT default to manually querying AzDO APIs or rely solely on `gh pr checks` pass/fail counts.
 
 
 
 
109 
110**When to use it:**
111- "How does CI look?" / "Is CI green?" / "Can we merge?"
112- "What's failing?" / "Are these known failures?"
113- "Is this PR safe to merge?" / "Any CI concerns?"
114- After any PR push to verify the build
115 
116**Verifying specific tests:** When asked "did test X pass?" or "did the new test run?", query the **actual AzDO test results** — do NOT infer whether a test ran by inspecting code attributes. Class-level traits, base class categories, and assembly-level attributes can all cause a test to run even when the method itself has no visible category. Check the evidence, not the code.
 
 
117 
118**Anti-pattern:** Writing ad-hoc scripts to parse AzDO build timelines. The skills handle Helix work item details, known issue cross-referencing, and test result aggregation that manual approaches miss.
119 
120### Gradle / Maven Dependency Failures (CFSClean)
121 
122The official CI build uses CFSClean network isolation which blocks `repo.maven.apache.org`. All Gradle/Maven dependencies resolve through the `dotnet-public-maven` Azure Artifacts feed.
123 
124**If CI fails with Gradle 401 errors** like `"No local versions of package"` or `"Please provide authentication to save package from upstream"`, it means a Maven package hasn't been ingested into the feed yet. **Fix:** run `./eng/ingest-maven-deps.sh` locally to pre-populate the feed. See `src/Core/AndroidNative/settings.gradle` for details.
125 
126**Do NOT upgrade Gradle past 8.x** — the Android SDK's `net.android.init.gradle.kts` is incompatible with Gradle 9.x (`dotnet/android#10738`).
 
 
 
 
 
 
127 
128### Code Formatting
129 
130Always format code before committing:
 
 
 
 
 
131 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132```bash
133dotnet format Microsoft.Maui.sln --no-restore --exclude Templates/src --exclude-diagnostics CA1822
 
134```
135 
136## Contribution Guidelines
 
 
 
 
 
137 
138### Handling Existing PRs for Assigned Issues
139 
140**🚨 CRITICAL REQUIREMENT: Always develop your own solution first, then compare with existing PRs.**
141 
1421. **Develop your own solution first** - Analyze the issue independently and design your approach without looking at existing PRs
1432. **Search for existing PRs** - After developing your solution, search for open PRs addressing the same issue
1443. **Compare and evaluate** - Examine existing PR approaches and decide which solution better addresses the issue
1454. **Document your decision** - In your PR description, compare your solution to existing PRs and explain why you chose your approach, including concerns with alternatives
1465. **Improve either solution** - Whether using your solution or an existing one, enhance with better tests, code quality, error handling, or documentation
147 
148### Auto-Generated Files (Never Commit)
 
 
 
149 
150These files are auto-generated and must NOT be committed:
151- `cgmanifest.json` - Generated during CI builds
152- `templatestrings.json` - Auto-generated localization
 
153 
154**For AI agents:** Always reset changes to these files before committing.
 
 
 
155 
156### PublicAPI.Unshipped.txt File Management
 
 
157 
158When working with public API changes:
159- **Never disable analyzers** to bypass PublicAPI.Unshipped.txt issues
160- **Always add correct API entries** to PublicAPI.Unshipped.txt files
161- **Use `dotnet format analyzers`** if having trouble
162- **If files are incorrect**: Revert all changes, then add only the necessary new API entries
163 
164### Branching
165- `main` - For bug fixes without API changes
166- The highest `netN.0` branch (by convention) - For new features and API changes. To find it, run `git fetch origin` then: `git for-each-ref --sort=-version:refname --count=1 --format='%(refname:lstrip=3)' refs/remotes/origin/net*.0`
167 
168### Git Workflow (Copilot CLI Rules)
 
 
 
 
169 
170**🚨 CRITICAL Git Rules for Copilot CLI:**
 
 
 
 
171 
1721. **NEVER commit directly to `main`** - Always create a feature branch for your work. Direct commits to `main` are strictly prohibited.
 
 
 
 
 
173 
1742. **When amending an existing PR, work on the PR's branch directly** - Do NOT create a separate branch off a PR branch. The PR branch already IS a feature branch. Creating a new branch off it means CI won't run on the original PR, defeating the purpose. Use `gh pr checkout` to switch to the PR branch, make your changes, commit, **then** ask before pushing so the user can review locally first.
 
 
 
175 
1763. **Do NOT rebase, squash, or force-push** unless explicitly requested by the user. These operations rewrite git history and can cause problems for other contributors. Default behavior should be regular commits and pushes.
177 
178**Safe Git Workflow:**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179```bash
180# Create a feature branch (NEVER work directly on main)
181git checkout -b feature/issue-12345
182 
183# Make commits normally
184git add .
185git commit -m "Fix: Description of the change"
186 
187# Push to remote (for new branches)
188git push -u origin feature/issue-12345
 
189 
190# For subsequent pushes on the same branch
191git push
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192```
193 
194**When asked to update an existing PR:**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195```bash
196# Check out the PR branch directly (do NOT create a new branch off it)
197gh pr checkout 12345
198 
199# Make fixes and commit to the PR branch
200git add .
201git commit -m "Fix: Description of the change"
 
 
 
 
 
202```
2031. **STOP and ask the user** before pushing: "Changes are committed locally. Would you like me to push these changes to the PR?"
2042. Exception: If the user's instructions explicitly include pushing, proceed without asking.
205 
206### Documentation
207- Update XML documentation for public APIs
208- Follow existing code documentation patterns
209- Update relevant docs in `docs/` folder when needed
210 
211### Opening PRs
212 
213All PRs are required to have this at the top of the description:
214 
 
 
 
 
215```
216<!-- Please let the below note in for people that find this PR -->
217> [!NOTE]
218> Are you waiting for the changes in this PR to be merged?
219> It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220```
221 
222Always put that at the top, without the block quotes. Without it, users will NOT be able to try the PR and your work will have been in vain!
223 
 
 
 
 
224 
 
225 
226## Custom Agents and Skills
227 
228The repository includes specialized custom agents and reusable skills for specific tasks.
229 
230### Skills vs Agents
 
 
 
231 
232| Aspect | Skills | Agents |
233|--------|--------|--------|
234| **Invoke** | `/skill-name` or direct request | Delegate to agent |
235| **Output** | Analysis, recommendations | Actions, changes applied |
236| **Interaction** | Interactive discussion | Autonomous workflow |
237| **Example** | `/learn-from-pr` → recommendations | learn-from-pr agent → applies changes |
238 
239### Available Custom Agents
 
240 
2411. **pr** - Sequential 4-phase workflow for reviewing and working on PRs
242 - **Use when**: A PR already exists and needs review or work, OR an issue needs a fix
243 - **Capabilities**: PR review, test verification, fix exploration, alternative comparison
244 - **Trigger phrases**: "review PR #XXXXX", "work on PR #XXXXX", "fix issue #XXXXX", "continue PR #XXXXX"
245 - **Do NOT use for**: Just running tests manually → Use `sandbox-agent`
246 
2472. **write-tests-agent** - Agent for writing tests. Determines test type (UI vs XAML) and invokes the appropriate skill (`write-ui-tests`, `write-xaml-tests`)
248 - **Use when**: Creating new tests for issues or PRs
249 - **Capabilities**: Test type determination (UI and XAML), skill invocation, test verification
250 - **Trigger phrases**: "write tests for #XXXXX", "create tests", "add test coverage"
251 
2523. **sandbox-agent** - Specialized agent for working with the Sandbox app for testing, validation, and experimentation
253 - **Use when**: User wants to manually test PR functionality or reproduce issues
254 - **Capabilities**: Sandbox app setup, Appium-based manual testing, PR functional validation
255 - **Trigger phrases**: "test this PR", "validate PR #XXXXX in Sandbox", "reproduce issue #XXXXX", "try out in Sandbox"
256 - **Do NOT use for**: Code review (use pr agent), writing automated tests (use write-tests-agent)
257 
2584. **learn-from-pr** - Extracts lessons from PRs and applies improvements to the repository
259 - **Use when**: After complex PR, want to improve instruction files/skills based on lessons learned
260 - **Capabilities**: Analyzes PR, identifies failure modes, applies improvements to instruction files, skills, code comments
261 - **Trigger phrases**: "learn from PR #XXXXX and apply improvements", "improve repo based on what we learned", "update skills based on PR"
262 - **Output**: Applied changes to instruction files, skills, architecture docs, code comments
263 - **Do NOT use for**: Analysis only without applying changes → Use `/learn-from-pr` skill instead
264 
2655. **release-readiness-agent** - Assesses ship-readiness for a .NET MAUI release branch — both **SR** (`release/*-srN`) and **Preview** (`release/*-previewN`)
266 - **Use when**: A release (SR or Preview) is approaching ship date and you need a synthesized verdict with WorkIQ/MCP enrichment on top of the deterministic report — **or** for a portfolio question across all active releases ("status on releases", "what needs attention across releases") where the user may not know which releases exist
267 - **Capabilities**: Resolves the branch (SR or Preview) from natural language, picks the right script (`Get-ReleaseReadiness.ps1` for SR, `Get-PreviewReadiness.ps1` for Preview), enriches `rejected-from-sr` candidates with WorkIQ context (SR lane), patches `UNKNOWN` ship-check rows via MCP (`maestro_default_channels`, `maestro_builds`), presents an overall verdict
268 - **Trigger phrases**: "is SR7 ready to ship", "release readiness for release/10.0.1xx-sr7", "survey the SR8 branch", "how does net11 preview6 look", "is preview6 ready to cut", "release readiness for release/11.0.1xx-preview6" — **plus portfolio / cross-release questions with no specific release named**: "give me a status on releases", "release status overview", "what's the status across all releases", "what needs attention across releases", "what's next for MAUI releases"
269 - **Output**: Verdict (Ready / Conditionally Ready / Not Ready) + per-candidate classification (SR) or per-section table (Preview) + actionable next steps
270 - **Do NOT use for**: Programmatic / scripted consumers that just need the raw JSON — use the `release-readiness` skill directly. Reviewing a single PR (use **pr**). Running tests manually (use **sandbox-agent**).
271 
272### Reusable Skills
 
 
 
273 
274Skills are modular capabilities that can be invoked directly or used by agents. Located in `.github/skills/`:
275 
276#### User-Facing Skills
277 
2781. **pr-review** (`.github/skills/pr-review/SKILL.md`)
279 - **Purpose**: End-to-end PR review orchestrator — 3 phases: pr-preflight, try-fix, pr-report. Gate runs separately before this skill via Review-PR.ps1.
280 - **Trigger phrases**: "review PR #XXXXX", "work on PR #XXXXX", "fix issue #XXXXX", "continue PR #XXXXX"
281 - **Capabilities**: Multi-model fix exploration, alternative comparison, PR review recommendation
282 - **Do NOT use for**: Just running tests manually → Use `sandbox-agent`
283 - **Phase instructions** (in `.github/pr-review/`):
284 - `pr-preflight.md` — Context gathering from issue/PR
285 - `pr-report.md` — Final recommendation
286 - **Phase skill**: `try-fix` — Multi-model fix exploration
287 - **Note**: Gate (test verification) runs as a script step in `Review-PR.ps1` before this skill is invoked. Gate result is passed in the prompt.
288 
2892. **issue-triage** (`.github/skills/issue-triage/SKILL.md`)
290 - **Purpose**: Query and triage open issues that need milestones, labels, or investigation
291 - **Trigger phrases**: "find issues to triage", "show me old Android issues", "what issues need attention"
292 - **Scripts**: `init-triage-session.ps1`, `query-issues.ps1`, `record-triage.ps1`
293 
2942. **find-reviewable-pr** (`.github/skills/find-reviewable-pr/SKILL.md`)
295 - **Purpose**: Finds open PRs in dotnet/maui and dotnet/docs-maui that need review
296 - **Trigger phrases**: "find PRs to review", "show milestoned PRs", "find partner PRs"
297 - **Scripts**: `query-reviewable-prs.ps1`
298 - **Categories**: P/0, milestoned, partner, community, recent, docs-maui
299 
3003. **pr-finalize** (`.github/skills/pr-finalize/SKILL.md`)
301 - **Purpose**: Verifies PR title and description match actual implementation, AND performs code review for best practices before merge.
302 - **Trigger phrases**: "finalize PR #XXXXX", "check PR description for #XXXXX", "review commit message"
303 - **Used by**: Before merging any PR, when description may be stale
304 - **Note**: Does NOT require agent involvement or session markdown - works on any PR
305 - **🚨 CRITICAL**: NEVER use `--approve` or `--request-changes` - only post comments. Approval is a human decision.
306 
3074. **code-review** (`.github/skills/code-review/SKILL.md`)
308 - **Purpose**: Reviews PR code changes for correctness, safety, and consistency with MAUI conventions. Walks through a MAUI-specific checklist covering handler lifecycle, platform code, safe area, threading, public API, and test patterns.
309 - **Trigger phrases**: "review code for PR #XXXXX", "code review PR #XXXXX", "review this PR's code"
310 - **Note**: Standalone skill — uses independence-first assessment (reads code before PR description to avoid anchoring bias). Can be used by any agent or invoked directly.
311 - **🚨 CRITICAL**: NEVER use `--approve` or `--request-changes` — only post comments. Approval is a human decision.
312 
3135. **learn-from-pr** (`.github/skills/learn-from-pr/SKILL.md`)
314 - **Purpose**: Analyzes completed PR to identify repository improvements (analysis only, no changes applied)
315 - **Trigger phrases**: "what can we learn from PR #XXXXX?", "how can we improve agents based on PR #XXXXX?"
316 - **Used by**: After complex PRs, when agent struggled to find solution
317 - **Output**: Prioritized recommendations for instruction files, skills, code comments
318 - **Note**: For applying changes automatically, use the learn-from-pr agent instead
319 
3206. **write-ui-tests** (`.github/skills/write-ui-tests/SKILL.md`)
321 - **Purpose**: Creates UI tests for GitHub issues and verifies they reproduce the bug
322 - **Trigger phrases**: "write UI tests for #XXXXX", "create UI test for issue", "add UI test coverage"
323 - **Output**: Test files that fail without fix, pass with fix
324 
3257. **write-xaml-tests** (`.github/skills/write-xaml-tests/SKILL.md`)
326 - **Purpose**: Creates XAML unit tests for XAML parsing, compilation, and source generation
327 - **Trigger phrases**: "write XAML tests for #XXXXX", "test XamlC behavior", "reproduce XAML parsing bug"
328 - **Output**: Test files for Controls.Xaml.UnitTests
329 
3309. **verify-tests-fail-without-fix** (`.github/skills/verify-tests-fail-without-fix/SKILL.md`)
331 - **Purpose**: Verifies tests catch the bug before fix and pass with fix. Auto-detects test type (UI, device, unit, XAML) and dispatches to the appropriate runner.
332 - **Two modes**: Verify failure only (test creation) or full verification (test + fix)
333 - **Used by**: After creating tests, before considering PR complete
334 
33510. **run-integration-tests** (`.github/skills/run-integration-tests/SKILL.md`)
336 - **Purpose**: Build, pack, and run .NET MAUI integration tests locally
337 - **Trigger phrases**: "run integration tests", "test templates locally", "run macOSTemplates tests", "run RunOniOS tests"
338 - **Categories**: Build, WindowsTemplates, macOSTemplates, Blazor, MultiProject, Samples, AOT, RunOnAndroid, RunOniOS
339 - **Note**: **ALWAYS use this skill** instead of manual `dotnet test` commands for integration tests
340 
34111. **dependency-flow** (`.github/skills/dependency-flow/SKILL.md`)
342 - **Purpose**: MAUI-specific dependency flow rules, channel conventions, and feed lookup workflows
343 - **Trigger phrases**: "feeds for .NET MAUI X.Y.Z", "where is MAUI build", "promote build to public feed", "what channels is MAUI on", "subscription health for MAUI"
344 - **Wraps**: `maestro-cli` skill (from `dotnet-dnceng@dotnet-arcade-skills` plugin) and maestro MCP tools
345 - **Note**: Provides MAUI-specific guardrails on top of core Maestro/darc operations — channel naming, safety deny-list, input validation, and prompt injection defense
346 
34712. **release-readiness** (`.github/skills/release-readiness/SKILL.md`)
348 - **Purpose**: Deterministic ship-readiness engine for .NET MAUI release branches — both **SR** (`release/*-srN`) and **Preview** (`release/*-previewN`). Surveys CI, computes what's actually shipping, classifies open regressions, identifies port candidates and rejected backports
349 - **Trigger phrases**: "release readiness for SRN", "is SR7 ready to ship", "survey the SR branch", "release readiness for preview6", "how does preview6 look (deterministic)", "status across all releases" (reads the live `[Release Readiness]` tracker issues by body marker — no survey re-run needed)
350 - **Scripts**: `Get-ReleaseReadiness.ps1` (SR lane), `Get-PreviewReadiness.ps1` (Preview lane), `Find-ReleaseReadinessTrackers.ps1` (tracker discovery)
351 - **Output**: JSON + Markdown report, list of source PRs, classification of regression issues (in-sr-active, rejected-from-sr, no-fix-yet, etc.)
352 - **Note**: Deterministic and reproducible — no MCP, no LLM judgment. Use **this skill directly** when you need raw output for a script, dashboard, cron job, or programmatic consumer. For natural-language verdict synthesis with WorkIQ enrichment, use the **`release-readiness-agent`** instead.
353 
354#### Internal Skills (Used by Agents)
 
 
 
355 
35613. **try-fix** (`.github/skills/try-fix/SKILL.md`)
357 - **Purpose**: Proposes ONE independent fix approach, applies it, tests, records result with failure analysis, then reverts
358 - **Used by**: pr agent Phase 3 (Fix phase) - rarely invoked directly by users
359 - **Behavior**: Reads prior attempts to learn from failures. Max 5 attempts per session.
360 - **Output**: Updates session markdown with attempt results and failure analysis
361 
362### Using Custom Agents
363 
364**Delegation Policy**: When user request matches agent trigger phrases, **ALWAYS delegate to the appropriate agent immediately**. Do not ask for permission or explain alternatives unless the request is ambiguous.
365 
366**Examples of correct delegation**:
367- User: "Review PR #12345" → Immediately invoke **pr** agent
368- User: "Test this PR" → Immediately invoke **sandbox-agent**
369- User: "Fix issue #67890" (no PR exists) → Suggest using `/delegate` command
370- User: "Write tests for issue #12345" → Immediately invoke **write-tests-agent**
371- User: "Is SR7 ready to ship?" → Immediately invoke **release-readiness-agent**
372- User: "How does net11 preview6 look?" → Immediately invoke **release-readiness-agent**
373- User: "Give me a status on releases / what needs attention across releases?" → Immediately invoke **release-readiness-agent** (portfolio mode — it enumerates active releases by reading the `[Release Readiness]` tracker issues; don't ask "which release?")
374- User: "Give me the raw release-readiness JSON for SR8" → Use the **release-readiness** skill directly (no enrichment needed)
375 
376**When NOT to delegate**:
377- User asks "What does PR #12345 do?" → Informational query, handle yourself
378- User asks "How do I test PRs?" → Documentation query, handle yourself
379- User has follow-up questions after agent completes → Continue the conversation yourself
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotnet/maui · .github/instructions/sandbox.instructions.md
@@ +1 @@
1---
2description: "Comprehensive guide for working with the .NET MAUI Sandbox app for testing, validation, and experimentation"
3applyTo: "src/Controls/samples/Controls.Sample.Sandbox/**"
4---
5 
6# Sandbox Testing Guide
7 
8Comprehensive guide for working with the .NET MAUI Sandbox app for manual testing, PR validation, issue reproduction, and experimentation with MAUI features.
9 
10## When This Applies
11 
12This guide applies when you:
13- Work with files in `src/Controls/samples/Controls.Sample.Sandbox/`
14- User asks to "test this PR" or "validate PR #XXXXX" in Sandbox
15- User asks to "reproduce issue #XXXXX" in Sandbox
16- User wants to deploy to iOS/Android for manual testing
17- User mentions Sandbox app by name in testing context
18 
19## 🚨 CRITICAL VALIDATION RULES - READ FIRST
20 
21**YOU MUST FOLLOW THESE RULES WHEN RUNNING SANDBOX TESTS:**
22 
23### What You NEVER Do (Absolute Rules)
24 
25- ❌ **NEVER** assume test completion without validation
26- ❌ **NEVER** claim success based on HTTP 200 responses alone (element found ≠ test completed)
27- ❌ **NEVER** skip the mandatory validation checklist
28- ❌ **NEVER** proceed without verifying device logs show expected behavior
29- ❌ **NEVER** assume Appium connection means test finished
30- ❌ **NEVER** claim button was tapped without checking device logs
31- ❌ **NEVER** switch branches (e.g., `git checkout main`) during reproduction - stay on current branch
 
 
32 
33### What You ALWAYS Do (Mandatory Steps)
34 
35- ✅ **ALWAYS** save full output to file for analysis
36- ✅ **ALWAYS** check for errors/exceptions FIRST before claiming success
37- ✅ **ALWAYS** verify "Test completed" marker appears in output
38- ✅ **ALWAYS** verify expected test actions in logs (Tapping, Screenshot, etc.)
39- ✅ **ALWAYS** check device logs for Console.WriteLine markers (e.g., "SANDBOX: ...")
40- ✅ **ALWAYS** verify artifacts exist (screenshots, if test captures them)
41 
42### Rule 1: NEVER ASSUME TEST COMPLETION
43- ❌ **DO NOT** assume the test completed successfully just because Appium connected
44- ❌ **DO NOT** assume success based on HTTP 200 responses (element found ≠ test completed)
45- ✅ **DO** verify test completion by checking for completion markers in output
46- ✅ **DO** search for "Test completed", "═══════", or final summary messages
47 
48### Rule 2: ALWAYS VALIDATE TEST OUTPUT
49After running BuildAndRunSandbox.ps1, you MUST:
501. **Save full output to file**: `pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform ios > CustomAgentLogsTmp/Sandbox/build-run-output.log 2>&1`
512. **Check for errors FIRST**: `grep -E "ERROR|Exception|failed" CustomAgentLogsTmp/Sandbox/build-run-output.log`
523. **Verify completion markers**: `grep "Test completed\|══════" CustomAgentLogsTmp/Sandbox/build-run-output.log`
534. **Check for expected actions**: `grep "Tapping\|Screenshot saved\|switched to" CustomAgentLogsTmp/Sandbox/build-run-output.log`
54 
55### Rule 3: VALIDATE DEVICE LOGS FOR EXPECTED BEHAVIOR
56- ✅ **DO** check device logs confirm your expected test actions happened
57- ✅ **DO** grep for your Console.WriteLine markers (e.g., "SANDBOX.*CLICKED")
58- ❌ **DO NOT** claim the test worked without verifying device logs show the action
59 
60### Rule 4: SYSTEMATIC VALIDATION CHECKLIST
61After EVERY test run, verify ALL of these **IN THIS ORDER**:
 
 
 
 
 
 
62 
63```bash
64# Step 1: Check for errors/exceptions FIRST
65grep -iE "error|exception|failed" CustomAgentLogsTmp/Sandbox/build-run-output.log | grep -v "no such element" | head -20
 
 
66 
67# Step 2: Verify expected test actions (MOST IMPORTANT - proves test actually ran)
68grep -E "Tapping|Screenshot saved|Found.*element|Clicking|Entering text" CustomAgentLogsTmp/Sandbox/build-run-output.log
69 
70# Step 3: Verify test completion marker
71grep "Test completed" CustomAgentLogsTmp/Sandbox/build-run-output.log
72 
73# Step 4: Verify device logs show expected behavior
74grep "SANDBOX" CustomAgentLogsTmp/Sandbox/android-device.log # or ios-device.log
 
 
 
75 
76# Step 5: Check screenshots were saved (if test captures them)
77ls -lh CustomAgentLogsTmp/Sandbox/*.png
78 
79# Step 6: Check exit code
80echo $? # Should be 0 for success
81```
82 
83**CRITICAL**: If Step 2 shows NO test actions, the test didn't actually run even if it "completed successfully". Update your Appium test and rerun.
84 
85**If ANY of these checks fail, the test DID NOT complete successfully. Investigate and fix before proceeding.**
 
 
 
86 
87---
88 
89## 🚨 WARNING: "Test Completed Successfully" ≠ Test Actually Worked
90 
91**CRITICAL UNDERSTANDING**: The message "✅ Test completed successfully" only means:
92- ✅ Appium test script finished running without crashing
93- ✅ Script exit code was 0
 
 
94 
95**It does NOT mean**:
96- ❌ Appium found your UI elements
97- ❌ Buttons were clicked
98- ❌ Navigation happened
99- ❌ Your test scenario actually ran
100 
101### Example of False Success
102 
103**What you see in output**:
104```
105✅ Test completed successfully
106 
107╔═══════════════════════════════════════════════════════════╗
108║ Test Summary ║
109╠═══════════════════════════════════════════════════════════╣
110║ Platform: ANDROID ║
111║ Device: emulator-5554 ║
112║ Result: SUCCESS ✅ ║
113╚═══════════════════════════════════════════════════════════╝
114```
115 
116**What actually happened**:
117```bash
118# Check the logs:
119grep "no such element" CustomAgentLogsTmp/Sandbox/build-run-output.log
120# Result: 20+ lines of "no such element" errors
121 
122# The test looked for "InstructionLabel" which doesn't exist in MainPage
123# Appium never found ANY elements
124# Test script just gave up and exited with code 0
125# NO ACTUAL TESTING WAS PERFORMED
126```
127 
128### How to Detect False Success
129 
130**MANDATORY check after EVERY "successful" test**:
131```bash
132# Look for actual test actions in output
133grep -E "Tapping|Clicking|Found element|Screenshot saved" CustomAgentLogsTmp/Sandbox/build-run-output.log
134```
135 
136**If grep returns NOTHING → FALSE SUCCESS**:
137- Test didn't actually do anything
138- Template test is looking for elements that don't exist
139- You MUST update `CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs` to match your MainPage
140- Rerun BuildAndRunSandbox.ps1 after updating test
141 
142**If grep returns multiple lines → REAL SUCCESS**:
143- Test found elements and interacted with them
144- Proceed with full validation checklist
145 
146---
147 
148## Purpose
149 
150Work with the Sandbox app for manual testing, PR validation, issue reproduction, and experimentation with MAUI features.
151 
152## When to Use Sandbox Testing
153 
154- ✅ User asks to "test this PR" (functional testing, not code review)
155- ✅ User asks to "validate PR #XXXXX" or "validate PR #XXXXX in Sandbox"
156- ✅ User asks to "reproduce issue #XXXXX" or "try out issue #XXXXX"
157- ✅ User asks to "try out" or "experiment with" a feature in Sandbox
158- ✅ PR modifies core MAUI functionality (controls, layouts, platform code)
159- ✅ Need to manually verify a fix works on device/simulator
160- ✅ Need to create a quick test scenario for hands-on validation
161 
162## When NOT to Use Sandbox
163 
164- ❌ User asks to "review PR #XXXXX" → Use **pr** agent for code review
165- ❌ User asks to "write tests" or "create automated tests" → Use **write-tests-agent**
166- ❌ User asks to "validate the UI tests" or "verify test quality" → Review test code instead
167- ❌ User asks to "fix issue #XXXXX" (no PR exists) → Suggest `/delegate` command
168- ❌ PR only adds documentation (no code changes to test)
169- ❌ PR only modifies build scripts (no functional changes)
170 
171## Distinction: Code Review vs. Functional Testing
172 
173**Code Review** (pr-review skill):
174- Analyzes code quality, patterns, best practices
175- Reviews test coverage and correctness
176- Checks for potential bugs or issues in the code itself
177- Trigger: "review PR", "work on PR"
178 
179**Functional Testing** (sandbox-agent):
180- Builds and deploys PR to device/simulator
181- Manually validates the fix works as expected
182- Reproduces issues and verifies they're resolved
183- Trigger: "test this PR", "validate PR in Sandbox", "reproduce issue"
184 
185## 🚨 Critical Requirements for Android Testing
186 
187**ANDROID-ONLY REQUIREMENT - appium:noReset**
188 
189⚠️ **This ONLY applies to Android, NOT iOS**
190 
191When testing on Android, the Appium test script **MUST** have this capability:
192 
193```csharp
194// ANDROID ONLY - Do NOT add this for iOS
195if (PLATFORM == "android")
196{
197 options.AddAdditionalAppiumOption("appium:noReset", true);
198}
199```
200 
201**Why this is critical for Android:**
202- Without `noReset`, Appium clears app data between runs
203- This breaks .NET MAUI's Fast Deployment mechanism on Android
204- App crashes with: `"No assemblies found in '.../__override__/...' ... Assuming this is part of Fast Deployment. Exiting..."`
205- The app will crash immediately on launch before any test can run
206 
207**iOS does NOT need this** - iOS deployment works differently and doesn't use Fast Deployment
208 
209**Where to set it:**
210- Template: `.github/scripts/templates/RunWithAppiumTest.template.cs` (line ~68, Android section only)
211- Active test: `CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs` (Android section only)
212 
213**Platform detection is automatic** - The template automatically detects Android vs iOS from the UDID format, so you don't need to manually set the platform. The `if (PLATFORM == "android")` block will execute automatically when testing on Android.
214 
215**⚠️ NEVER REMOVE THIS CAPABILITY FROM ANDROID** - All Android tests depend on it
216 
217---
218 
219## Core Workflow
220 
221**🚨 CRITICAL RULES FOR ENTIRE WORKFLOW:**
222- **ALWAYS use BuildAndRunSandbox.ps1 script** for building, deploying, and testing
223- **NEVER use manual `dotnet build`, `adb`, or `xcrun` commands**
224- **NEVER switch branches during reproduction** - stay on the current branch
225- **ALWAYS stop and ask user if you cannot reproduce** - do not try alternative branches
226- The script handles device detection, build, deployment, and test execution automatically
227- See "BuildAndRunSandbox.ps1 Script" section below for full details
228 
229---
230 
231### Step 1: Understand Issue (DO NOT Checkout PR Unless Instructed)
232 
233**⚠️ IMPORTANT**: Only checkout a PR if the user explicitly asks you to test a specific PR. For general issue reproduction, work on the current branch.
234 
235```bash
236# ONLY if user explicitly asks to test a PR:
237gh pr checkout <PR_NUMBER>
238```
239 
240**Understand the issue thoroughly:**
241- Read issue report or PR description
242- Identify what bug needs to be reproduced
243- Note affected platforms
244- Look for reproduction steps in the issue
245- If testing a PR: Review PR changes to understand the fix
246 
247---
248 
249### Step 2: Create Test Scenario in Sandbox
250 
251**Choose test scenario source (in priority order):**
 
 
 
 
252 
2531. **From Issue Reproduction** (Preferred)
254 - Look for "Reproduction" or "Steps to Reproduce" in the linked issue
255 - Use the exact scenario the user reported
256 - This proves you're testing what the user experienced
257 
2582. **From PR's UI Tests** (Alternative)
259 - Check if PR includes files in `TestCases.HostApp/Issues/IssueXXXXX.*`
260 - Adapt the test page code to Sandbox
261 - Simplify if needed for manual testing
262 
2633. **Create Your Own** (Last Resort)
264 - If no repro available, design scenario based on PR changes
265 - Focus on the specific code paths modified by the fix
266 - Keep it simple and focused
267 
268**Files to modify**:
269- `src/Controls/samples/Controls.Sample.Sandbox/MainPage.xaml[.cs]` - UI and code for reproduction
270- `CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs` - Appium test script (MANDATORY - see setup below)
271 
272**Setting up the Appium test file (MANDATORY):**
 
 
 
 
273 
274🚨 **CRITICAL**: Update Appium test BEFORE running script. Template will give FALSE SUCCESS otherwise.
 
 
275 
2761. **Create test file**:
277 ```bash
278 mkdir -p CustomAgentLogsTmp/Sandbox
279 cp .github/scripts/templates/RunWithAppiumTest.template.cs CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs
280 ```
281 
2822. **Update test to match MainPage**:
283 - Check AutomationIds: `grep AutomationId MainPage.xaml`
284 - Update test to use those IDs (not template defaults)
285 - Add test logic: tap buttons, verify labels
286 - Add Console.WriteLine markers for debugging
287 
2883. **Example**:
289 ```bash
290 # Check MainPage
291 grep 'AutomationId=' MainPage.xaml
292 # Update test: App.WaitForElement("NavigateButton");
293 ```
294 
295**Checklist**:
296- ✅ Add AutomationIds to MainPage.xaml elements
297- ✅ Update RunWithAppiumTest.cs to match
298- ✅ Add SANDBOX markers for debugging
299 
300**🚨 CRITICAL - Document Your Test Scenario:**
301 
302You MUST include in your final report:
303- ✅ **Source**: Where did the test scenario come from? (issue reproduction / PR UITest / custom)
304- ✅ **Why**: Why did you choose that source? (e.g., "Issue #XXXXX provides detailed repro steps")
305- ✅ **What**: What specific actions does your test perform? (e.g., "Tap button → verify label changes to 'Success'")
306- ✅ **Expected**: What behavior should occur? (from issue description or PR changes)
307 
308Without this documentation, user cannot verify you tested the right thing.
309 
310---
311 
312### Step 3: Test WITH PR Fix
313 
314**Platform Selection Decision Tree:**
315 
316Follow this flowchart in order - stop at the first match:
317 
318```
319┌─────────────────────────────────────────────────────────────────┐
320│ 1. Does PR title have platform tag? [Android], [iOS], etc. │
321│ YES → Test that platform ONLY │
322│ NO → Continue to step 2 │
323├─────────────────────────────────────────────────────────────────┤
324│ 2. Are ALL modified files in platform-specific paths? │
325│ (Platform/Android/, Platform/iOS/, *.Android.cs, etc.) │
326│ YES → Test that platform ONLY │
327│ NO → Continue to step 3 │
328├─────────────────────────────────────────────────────────────────┤
329│ 3. Does issue report mention a specific platform? │
330│ YES (one platform) → Test that platform ONLY │
331│ YES (multiple) → Test Android + iOS │
332│ NO → Continue to step 4 │
333├─────────────────────────────────────────────────────────────────┤
334│ 4. Is this high-risk cross-platform code? │
335│ (Controls/, Core/, layout, navigation, critical controls) │
336│ YES → Test Android + iOS │
337│ NO → Test Android ONLY (default - faster) │
338└─────────────────────────────────────────────────────────────────┘
339```
340 
341**Platform-specific path indicators:**
342- `Platform/Android/` or `Platform/iOS/` → Platform-specific
343- Files with `.Android.`, `.iOS.`, `.MacCatalyst.` in name → Platform-specific
344- `Controls/`, `Core/` without platform subfolders → Cross-platform
345 
346**Hard rule:** Never test more than 2 platforms unless user explicitly requests it.
347 
348**Run Test on Specific iOS Device/Version:**
349 
350When user requests a specific iOS version or device:
351 
3521. **Find the UDID for that device/version combination**:
353 ```bash
354 # Example: Find iPhone Xs with iOS 18.5
355 UDID=$(xcrun simctl list devices available --json | jq -r '
356 .devices
357 | to_entries
358 | map(select(.key | contains("iOS-18-5")))
359 | map(.value)
360 | flatten
361 | map(select(.name == "iPhone Xs"))
362 | first
363 | .udid
364 ')
365
366 echo "Found UDID: $UDID"
367 ```
368 
3692. **Pass the UDID to the script**:
370 ```bash
371 pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform ios -DeviceUdid "$UDID"
372 ```
373 
374**Examples:**
375- **"Run on iOS 18.5"** → Find iPhone Xs with iOS 18.5, get UDID, pass to script
376- **"Run on iPhone 15"** → Find iPhone 15 (any iOS), get UDID, pass to script
377- **"Run on iPhone 16 Pro with iOS 18.0"** → Find iPhone 16 Pro with iOS 18.0, get UDID, pass to script
378 
379---
380 
381## How the Template Works
382 
383**The template ALWAYS does the same thing:**
384 
3851. ✅ Verifies app launched successfully (WaitForElement)
3862. ✅ Optionally runs automated UI tests (if you add them)
3873. ✅ Exits WITHOUT closing the app (stays running for manual validation)
388 
389**Usage:**
390```bash
391# Copy the template
392cp .github/scripts/templates/RunWithAppiumTest.template.cs CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs
393 
394# OPTIONAL: Add automated test logic in the TEST LOGIC section
395# If you don't add test logic, it just verifies launch and exits
 
396 
397# Run the script
398pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform ios
399```
400 
401**Result:**
402- App launches and stays running
403- You can manually validate in the simulator
404- Test script exits without closing the app
405 
406---
407 
408## 🚨 CRITICAL: BuildAndRunSandbox.ps1 Script - ONLY Way to Deploy Sandbox
409 
410**YOU MUST ALWAYS USE THIS SCRIPT. NEVER USE MANUAL `dotnet build`, `adb`, or `xcrun` COMMANDS.**
411 
412### Script Location
413`.github/scripts/BuildAndRunSandbox.ps1`
414 
415### Basic Usage
416```powershell
417# Android
418pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform Android
419 
420# iOS (auto-detects device)
421pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform iOS
422 
423# iOS with specific device
424pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform iOS -DeviceUdid "YOUR-DEVICE-UDID"
425```
426 
427### What the Script Does Automatically
428- ✅ **Device detection and boot** - Finds and boots simulator/emulator
429- ✅ **UDID extraction** - Sets DEVICE_UDID environment variable
430- ✅ **Fresh app build** - Builds Sandbox project for target platform
431- ✅ **App deployment** - Installs and launches app
432- ✅ **Appium server management** - Starts/stops Appium automatically
433- ✅ **Log capture** - Saves device and Appium logs to `CustomAgentLogsTmp/Sandbox/`
434- ✅ **Test execution** - Runs your Appium test script
435 
436### Requirements Before Running
437Copy and update test file (see Step 2 above). Template looks for "InstructionLabel" which doesn't exist - update first!
438 
439**🚨 POST-TEST VALIDATION (MANDATORY):**
440 
441After script completes, run Rule 4 validation checklist (see above). If ANY check fails: investigate, fix, rerun.
442 
443**Key reminders**:
444- HTTP 200 = element found, NOT test completed
445- If no test actions in logs = FALSE SUCCESS
446- If Appium can't find initial element = app crashed or AutomationIds wrong
447 
448---
449 
450### 📝 Note for User
451 
452**Test scenario is ready in Sandbox for manual verification.**
453 
454**To verify bug reproduction (optional):**
455```bash
456# 1. Revert the PR fix files
457git checkout main -- [list specific fix files from PR]
458 
459# 2. Rerun test - bug should appear
460pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform [android|ios]
461 
462# 3. Restore fix
463git checkout HEAD -- [fix files]
464 
465# 4. Rerun test - bug should be gone
466pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform [android|ios]
467```
 
 
468 
469This proves the test scenario correctly reproduces the bug.
 
 
 
470 
471---
472 
473## 🔄 Iterative Testing Workflow (MANDATORY PROCESS)
474 
475**🚨 CRITICAL**: This is THE workflow for Sandbox testing. Do NOT use manual `adb`/`xcrun` commands to bypass it.
476 
477### The Required Loop
478 
479```
480┌─────────────────────────────────────────────────────────────┐
481│ 1. Update MainPage.xaml[.cs] with your test scenario │
482│ - Add UI elements for reproduction │
483│ - Add AutomationIds to all interactive elements │
484│ - Add Console.WriteLine markers for debugging │
485├─────────────────────────────────────────────────────────────┤
486│ 2. Update Appium test to match your MainPage │
487│ CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs │
488│ - Update element locators to match AutomationIds │
489│ - Add test logic (tap buttons, verify labels) │
490├─────────────────────────────────────────────────────────────┤
491│ 3. Run BuildAndRunSandbox.ps1 │
492│ pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform X │
493├─────────────────────────────────────────────────────────────┤
494│ 4. Validate results using SYSTEMATIC CHECKLIST │
495│ - Step 1: Check for errors/exceptions │
496│ - Step 2: Verify test actions (Tapping, etc.) │
497│ - Step 3: Verify "Test completed" │
498│ - Step 4: Check device logs for SANDBOX markers │
499│ - Step 5-6: Screenshots and exit code │
500├─────────────────────────────────────────────────────────────┤
501│ 5. Did ALL validation checks pass? │
502│ YES → Report success with summary (go to step 8) │
503│ NO → Continue to step 6 │
504├─────────────────────────────────────────────────────────────┤
505│ 6. Investigate failure from captured logs │
506│ - Read CustomAgentLogsTmp/Sandbox/android-device.log │
507│ - Read CustomAgentLogsTmp/Sandbox/build-run-output.log │
508│ - Identify root cause (element not found? crash?) │
509├─────────────────────────────────────────────────────────────┤
510│ 7. Fix the issue and LOOP BACK TO STEP 3 │
511│ - Update MainPage if UI/code issue │
512│ - Update RunWithAppiumTest.cs if test issue │
513│ - Update both if AutomationId mismatch │
514│ - Max 3 iterations before reporting as blocked │
515├─────────────────────────────────────────────────────────────┤
516│ 8. Report comprehensive summary to user │
517│ - Test scenario source and justification │
518│ - Validation results │
519│ - Verdict (success/partial/issues/blocked) │
520└─────────────────────────────────────────────────────────────┘
521```
522 
523### ❌ What NOT To Do
524 
525**Never use manual commands during testing**:
526- ❌ `adb logcat`, `adb shell`, `adb install`
527- ❌ `xcrun simctl spawn`, `xcrun simctl install`
528- ❌ `dotnet build`, `dotnet run`
529 
530**Why**: Script already captured everything. Manual commands show CURRENT state, not test execution state.
531 
532**✅ Correct**: Edit files → Rerun `BuildAndRunSandbox.ps1`
533 
534### ✅ Correct Iteration Example
535 
536**Most common case - Test fails to find element**:
537```bash
538# 1. Check what went wrong
539grep "no such element" CustomAgentLogsTmp/Sandbox/build-run-output.log
540 
541# 2. Check what DOES exist in MainPage
542grep AutomationId src/Controls/samples/Controls.Sample.Sandbox/MainPage.xaml
 
 
 
 
543 
544# 3. Fix MainPage: Add AutomationIds
545# Edit MainPage.xaml: <Button AutomationId="NavigateButton" ...
546 
547# 4. Fix test: Update to match
548# Edit RunWithAppiumTest.cs: App.WaitForElement("NavigateButton");
 
 
 
549 
550# 5. Rerun
551pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform android
552```
 
553 
554**When validation passes**: Report success with comprehensive summary
 
 
 
 
555 
556### When to Stop Iterating
 
 
 
 
 
557 
558- ✅ **All validation checks pass** → Report success with detailed summary
559- ❌ **Max 3 iterations reached** → **STOP and report**: "I wasn't able to reproduce the issue. What should I try next?"
560- ❌ **Build fails repeatedly** → **STOP and report**: "I wasn't able to reproduce the issue due to build failures. What should I try next?"
561- ❌ **Root cause unclear after log analysis** → **STOP and report**: "I wasn't able to reproduce the issue. What should I try next?"
562- ❌ **Issue appears to be PR bug, not test** → **STOP and report findings to user**: "I wasn't able to reproduce the issue - it appears there may be an issue with [details]. What should I try next?"
563- ❌ **Cannot reproduce the issue** → **STOP immediately**: "I wasn't able to reproduce the issue. What should I try next?"
564 
565**CRITICAL**: When you cannot reproduce or hit blockers, **PAUSE and ask the user**. Do NOT:
566- ❌ Switch to a different branch (e.g., `git checkout main`)
567- ❌ Try alternative approaches without asking first
568- ❌ Change the workflow significantly without user guidance
569 
570### Mental Model: The Script is Your Robot
571 
572BuildAndRunSandbox.ps1 handles: build → deploy → capture logs → run test → report
573 
574**Your workflow**: Edit files → Run script → Read logs → Fix issues → Repeat
 
 
 
 
 
 
 
 
 
575 
576---
 
 
 
577 
578## Output Format
 
 
 
 
579 
580Provide a concise test summary:
 
 
 
 
 
581 
582```markdown
583## PR Testing Summary
 
 
 
584 
585**PR**: #XXXXX - [Title]
586**Platform Tested**: Android/iOS
587**Issue**: [Brief description]
 
 
 
588 
589---
 
 
 
590 
591### Test Scenario Setup
 
 
 
592 
593**🚨 REQUIRED - Source of Test Scenario**:
594- **Source**: [From issue reproduction / From PR UITest / Custom scenario]
595- **Why this source**: [e.g., "Issue #XXXXX provides detailed repro steps" / "PR includes UITest that demonstrates the fix" / "No repro available, created scenario based on PR code changes"]
596- **Link to source**: [URL to issue comment with repro, or path to UITest file]
597 
598**What was tested**:
599- [Specific actions taken - e.g., "Tap 'Toggle RTL' button, then tap 'Show Dialog' button"]
600- [UI elements involved - e.g., "Button with AutomationId='ToggleButton', Dialog with Label"]
601- [Expected behavior - e.g., "Dialog should appear with correct RTL padding on label"]
 
602 
603---
 
 
 
 
604 
605### Test Results WITH PR Fix
 
 
 
 
 
606 
607**Observed Behavior**:
608- [What happened when running the test]
609- [Appium test results]
610- [Relevant log excerpts]
611 
612**Screenshots**: [Reference if taken, but not for validation]
 
 
 
 
613 
614---
615 
616### Verdict
617 
618✅ **FIX VALIDATED** - Test scenario completes successfully, expected behavior observed
619OR
620⚠️ **PARTIAL** - Fix appears to work but [note any concerns]
621OR
622❌ **ISSUES FOUND** - [Specific problems encountered]
623OR
624🚫 **CANNOT TEST** - [Build failures, setup issues, etc.]
 
 
625 
626---
627 
628### Notes for User
629- Test scenario is set up in Sandbox and ready for manual verification if needed
630- To verify bug reproduction without fix, revert PR changes: `git checkout main -- [fix files]`
631- Then rerun: `pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform [android|ios]`
632```
633 
634---
635 
636## Best Practices
637 
6381. **Use issue reproduction when available** - Most reliable test scenario
6392. **Adapt PR's UITests if no repro** - They're already designed to test the fix
6403. **Validate programmatically, reference visually** - Use Appium element queries for validation, screenshots only for additional context
6414. **Use colored backgrounds** - Makes layout issues visible
6425. **Add console markers** - Easy to grep logs
6436. **Test multiple iterations** - Race conditions need multiple runs (3-5 times)
6447. **Leave Sandbox as-is** - User will iterate on it after your testing
6458. **Document your test scenario thoroughly** - Include source (issue/UITest/custom), why you chose it, specific actions, and expected behavior so user can verify
646 
647**Screenshot Usage**:
648- ✅ Take screenshots for **context and reference** (e.g., showing layout before/after)
649- ✅ Include in report if they provide **additional insight** beyond what logs show
650- ❌ Do NOT rely on screenshots as **primary validation** - use Appium element queries and log analysis
651- ❌ Do NOT take screenshots just to show "it works" - validation should come from test assertions
652 
653---
654 
655## Log Capture and Review
656 
657### Where Logs Are Saved
658 
659After running BuildAndRunSandbox.ps1, all logs are in `CustomAgentLogsTmp/Sandbox/`:
660 
6611. **Android**: `CustomAgentLogsTmp/Sandbox/android-device.log`
6622. **iOS**: `CustomAgentLogsTmp/Sandbox/ios-device.log`
6633. **Appium**: `CustomAgentLogsTmp/Sandbox/appium.log`
664 
665### Viewing Logs
666 
667```bash
668# View device logs
669cat CustomAgentLogsTmp/Sandbox/android-device.log
670# or
671cat CustomAgentLogsTmp/Sandbox/ios-device.log
672 
673# Search for specific output
674grep "TEST OUTPUT" CustomAgentLogsTmp/Sandbox/android-device.log
675 
676# View Appium logs
677cat CustomAgentLogsTmp/Sandbox/appium.log
678```
679 
680### 📝 Adding Debug Logging to Your Test Scenario
681 
682**Use `Console.WriteLine` for logging** - it works on all platforms.
683 
684```csharp
685// Use a unique prefix for easy grep
686Console.WriteLine("SANDBOX: Button clicked");
687Console.WriteLine($"SANDBOX: Value is {myValue}");
688```
689 
690**Searching logs:**
691```bash
692grep "SANDBOX" CustomAgentLogsTmp/Sandbox/android-device.log
693grep "SANDBOX" CustomAgentLogsTmp/Sandbox/ios-device.log
694grep "SANDBOX" CustomAgentLogsTmp/Sandbox/catalyst-device.log
695```
696 
697---
698 
699## 🚨 ABSOLUTE RULE: BuildAndRunSandbox.ps1 is THE ONLY Deployment Method
700 
701**THIS IS MANDATORY. NOT A SUGGESTION.**
702 
703❌ If typing `adb`/`xcrun` commands during testing → STOP. You're violating the workflow.
704 
705**Why**: Manual commands show CURRENT state, not test execution state. Script already captured correct logs during test.
706 
707**❌ NEVER during testing**: `adb logcat`, `adb install`, `adb shell`, `xcrun simctl install/spawn`, `dotnet build/run`
708 
709**✅ ONLY exception**: Finding/booting specific iOS device BEFORE running script (`xcrun simctl list/boot`)
710 
711**Correct workflow**:
7121. Edit files (MainPage, RunWithAppiumTest.cs)
7132. Run: `pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform X`
7143. Analyze logs in `CustomAgentLogsTmp/Sandbox/` (android-device.log, appium.log)
7154. Fix issues, rerun script
716 
717**Expected logs**: `android-device.log` or `ios-device.log`, `appium.log`, `RunWithAppiumTest.cs`, optional screenshots
718 
719---
720 
721## Troubleshooting & Recovery
722 
723**Retry up to 3 times before reporting as blocked.** After each failure: analyze logs → fix → rerun script.
724 
725### Common Issues
726 
727| Issue | Recovery | Max Retries |
728|-------|----------|-------------|
729| Build error | Check SDK version, `dotnet tool restore` | 2 |
730| App crash | Check stack trace in device log, fix code/XAML | 3 |
731| Element not found | Verify AutomationIds match, check app loaded | 2 |
732| Fast Deployment (Android) | Add `appium:noReset` capability | 1 |
733| XAML parse error | Verify event handler exists in code-behind | 2 |
734 
735### Element Not Found Debugging
736 
737🚨 If Appium can't find initial element, app is NOT running correctly.
738 
739**Check**:
740```bash
741# Look for crashes
742grep -i "FATAL\|crash\|exception" CustomAgentLogsTmp/Sandbox/android-device.log | tail -20
743 
744# Verify app launched
745grep "SANDBOX.*MainPage" CustomAgentLogsTmp/Sandbox/android-device.log
746```
747 
748**Root causes**: App crashed, XAML parse error, AutomationId mismatch, Android Fast Deployment
749 
750### When to Stop & Report
751- ✅ **Continue**: Minor warnings, non-critical timeouts, platform differences
752- ❌ **Stop and ask user**: Can't checkout PR, build fails after max retries, SDK mismatch, root cause unclear, cannot reproduce issue
753 
754**When blocked, ALWAYS report to user with this format**:
755```markdown
756I wasn't able to reproduce the issue. Here's what I tried:
757 
7581. [What I attempted]
7592. [Issues encountered]
7603. [Current state of reproduction attempt]
761 
762What should I try next?
763```
764 
765**DO NOT** try alternative approaches without asking first. **DO NOT** switch branches.
766 
767### Test Shows Unexpected Behavior
768**Action**: Document and report
769 
770```markdown
771⚠️ Unexpected behavior during testing
772 
773**What I expected**: [Based on issue description]
774 
775**What I observed**: [Actual behavior]
776 
777**Test scenario**: [What was tested]
778 
779**Logs**: [Relevant excerpts]
780 
781**Question for user**: Is this expected behavior, or does this indicate an issue?
782```
783 
784---
785 
786## Common Mistakes to Avoid
787 
788- ❌ Using TestCases.HostApp for manual PR validation (use Sandbox)
789- ❌ Manual build/deploy commands instead of BuildAndRunSandbox.ps1
790- ❌ Testing only one platform when PR affects multiple
791- ❌ Using screenshots for validation (use Appium element queries)
792- ❌ Creating test scenario without checking issue for reproduction steps
793- ❌ Ignoring PR's existing UITests when available
794- ❌ Cleaning up or reverting Sandbox changes (user will iterate on it)
795 
796**Testing Tips**:
797- For layout bugs: Use `element.GetRect()` to measure positions
798- For SafeArea PRs: Measure child content position, not parent size
799- Add `Console.WriteLine("SANDBOX: ...")` markers for debugging
800 
801---
802 
803## Appendix: Cleanup (Only When User Requests)
804 
805⚠️ **DO NOT clean up after testing** - Leave Sandbox as-is so user can iterate on it.
806 
807Only use these commands if the **user explicitly requests cleanup**:
808 
809### Sandbox App Cleanup (User Request Only)
810```bash
811# Revert all changes to Sandbox app
812git checkout -- src/Controls/samples/Controls.Sample.Sandbox/
813```
814 
815### Sandbox Test Files Cleanup (User Request Only)
816```bash
817# Remove Appium test directory (gitignored)
818rm -rf CustomAgentLogsTmp/Sandbox/
819```
820 
@@ −1 +1 @@
11 ---
2−description: "Guidance for GitHub Copilot when working on the .NET MAUI repository."
2+description: "Comprehensive guide for working with the .NET MAUI Sandbox app for testing, validation, and experimentation"
3+applyTo: "src/Controls/samples/Controls.Sample.Sandbox/**"
34 ---
45  
5−# GitHub Copilot Development Environment Instructions
6+# Sandbox Testing Guide
67  
7−This document provides specific guidance for GitHub Copilot when working on the .NET MAUI repository. It serves as context for understanding the project structure, development workflow, and best practices.
8+Comprehensive guide for working with the .NET MAUI Sandbox app for manual testing, PR validation, issue reproduction, and experimentation with MAUI features.
89  
9−## Code Review Instructions
10+## When This Applies
1011  
11−When performing a code review on PRs that change functional code, run the pr-finalize skill to verify that the PR title and description accurately match the actual implementation. This ensures proper documentation and helps maintain high-quality commit messages.
12+This guide applies when you:
13+- Work with files in `src/Controls/samples/Controls.Sample.Sandbox/`
14+- User asks to "test this PR" or "validate PR #XXXXX" in Sandbox
15+- User asks to "reproduce issue #XXXXX" in Sandbox
16+- User wants to deploy to iOS/Android for manual testing
17+- User mentions Sandbox app by name in testing context
1218  
13−## Repository Overview
19+## 🚨 CRITICAL VALIDATION RULES - READ FIRST
1420  
15−**.NET MAUI** is a cross-platform framework for creating mobile and desktop applications with C# and XAML. This repository contains the core framework code that enables development for Android, iOS, iPadOS, macOS, and Windows from a single shared codebase.
21+**YOU MUST FOLLOW THESE RULES WHEN RUNNING SANDBOX TESTS:**
1622  
17−### Key Technologies
23+### What You NEVER Do (Absolute Rules)
1824  
19−- **.NET SDK** - Version is **ALWAYS** defined in `global.json` at repository root
20− - **main branch**: Latest stable .NET version
21− - **Feature branches**: Each `netN.0` branch targets the .NET N SDK. By convention, the highest `netN.0` branch is the current development branch for new features and API changes.
22−- **Cake build system** for compilation and packaging (`dotnet cake`)
23−- **MSBuild** with custom build tasks (must build `Microsoft.Maui.BuildTasks.slnf` first)
24−- **Testing frameworks**:
25− - **xUnit** - Unit tests (`*.UnitTests.csproj`)
26− - **NUnit** - UI tests (`TestCases.Shared.Tests`)
27− - **Appium WebDriver** - UI test automation
25+- ❌ **NEVER** assume test completion without validation
26+- ❌ **NEVER** claim success based on HTTP 200 responses alone (element found ≠ test completed)
27+- ❌ **NEVER** skip the mandatory validation checklist
28+- ❌ **NEVER** proceed without verifying device logs show expected behavior
29+- ❌ **NEVER** assume Appium connection means test finished
30+- ❌ **NEVER** claim button was tapped without checking device logs
31+- ❌ **NEVER** switch branches (e.g., `git checkout main`) during reproduction - stay on current branch
2832  
29−## Development Environment Setup
33+### What You ALWAYS Do (Mandatory Steps)
3034  
31−This guidance assumes:
32−- Repository is already cloned and tools are restored (`dotnet tool restore` completed)
33−- Build tasks are compiled (`Microsoft.Maui.BuildTasks.slnf` built successfully)
34−- Correct .NET SDK version installed (verify with `dotnet --version` against `global.json`)
35+- ✅ **ALWAYS** save full output to file for analysis
36+- ✅ **ALWAYS** check for errors/exceptions FIRST before claiming success
37+- ✅ **ALWAYS** verify "Test completed" marker appears in output
38+- ✅ **ALWAYS** verify expected test actions in logs (Tapping, Screenshot, etc.)
39+- ✅ **ALWAYS** check device logs for Console.WriteLine markers (e.g., "SANDBOX: ...")
40+- ✅ **ALWAYS** verify artifacts exist (screenshots, if test captures them)
3541  
36−### Platform-Specific Requirements
42+### Rule 1: NEVER ASSUME TEST COMPLETION
43+- ❌ **DO NOT** assume the test completed successfully just because Appium connected
44+- ❌ **DO NOT** assume success based on HTTP 200 responses (element found ≠ test completed)
45+- ✅ **DO** verify test completion by checking for completion markers in output
46+- ✅ **DO** search for "Test completed", "═══════", or final summary messages
3747  
38−- **Android**: OpenJDK 17 + Android SDK (install via `android` command after `dotnet tool restore`)
39−- **iOS/macOS**: Xcode (current stable version)
40−- **Windows**: Windows SDK
48+### Rule 2: ALWAYS VALIDATE TEST OUTPUT
49+After running BuildAndRunSandbox.ps1, you MUST:
50+1. **Save full output to file**: `pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform ios > CustomAgentLogsTmp/Sandbox/build-run-output.log 2>&1`
51+2. **Check for errors FIRST**: `grep -E "ERROR|Exception|failed" CustomAgentLogsTmp/Sandbox/build-run-output.log`
52+3. **Verify completion markers**: `grep "Test completed\|══════" CustomAgentLogsTmp/Sandbox/build-run-output.log`
53+4. **Check for expected actions**: `grep "Tapping\|Screenshot saved\|switched to" CustomAgentLogsTmp/Sandbox/build-run-output.log`
4154  
42−## Project Structure
55+### Rule 3: VALIDATE DEVICE LOGS FOR EXPECTED BEHAVIOR
56+- ✅ **DO** check device logs confirm your expected test actions happened
57+- ✅ **DO** grep for your Console.WriteLine markers (e.g., "SANDBOX.*CLICKED")
58+- ❌ **DO NOT** claim the test worked without verifying device logs show the action
4359  
44−### Important Directories
45−- `src/Core/` - Core MAUI framework code
46−- `src/Controls/` - UI controls and components
47−- `src/Essentials/` - Platform APIs and essentials
48−- `src/TestUtils/` - Testing utilities and infrastructure
49−- `docs/` - Development documentation
50−- `eng/` - Build engineering and tooling
51−- `.github/` - GitHub workflows and configuration
60+### Rule 4: SYSTEMATIC VALIDATION CHECKLIST
61+After EVERY test run, verify ALL of these **IN THIS ORDER**:
5262  
53−### Platform-Specific Code Organization
54−- **Android** specific code is inside folders labeled `Android`
55−- **iOS** specific code is inside folders labeled `iOS`
56−- **MacCatalyst** specific code is inside folders named `MacCatalyst`
57−- **Windows** specific code is inside folders named `Windows`
63+```bash
64+# Step 1: Check for errors/exceptions FIRST
65+grep -iE "error|exception|failed" CustomAgentLogsTmp/Sandbox/build-run-output.log | grep -v "no such element" | head -20
5866  
59−### Platform-Specific File Extensions
67+# Step 2: Verify expected test actions (MOST IMPORTANT - proves test actually ran)
68+grep -E "Tapping|Screenshot saved|Found.*element|Clicking|Entering text" CustomAgentLogsTmp/Sandbox/build-run-output.log
6069  
61−Platform-specific files use naming conventions to control compilation:
70+# Step 3: Verify test completion marker
71+grep "Test completed" CustomAgentLogsTmp/Sandbox/build-run-output.log
6272  
63−**File extension patterns**:
64−- `.windows.cs` - Windows TFM only
65−- `.android.cs` - Android TFM only
66−- `.ios.cs` - iOS and MacCatalyst TFMs (both)
67−- `.maccatalyst.cs` - MacCatalyst TFM only (does NOT compile for iOS)
73+# Step 4: Verify device logs show expected behavior
74+grep "SANDBOX" CustomAgentLogsTmp/Sandbox/android-device.log # or ios-device.log
6875  
69−**Important**: Both `.ios.cs` and `.maccatalyst.cs` files compile for MacCatalyst. There is no precedence mechanism that excludes one when the other exists.
76+# Step 5: Check screenshots were saved (if test captures them)
77+ls -lh CustomAgentLogsTmp/Sandbox/*.png
7078  
71−**Example**: If you have both `CollectionView.ios.cs` and `CollectionView.maccatalyst.cs`, both will compile for MacCatalyst builds. The `.maccatalyst.cs` file won't compile for iOS, but the `.ios.cs` file will compile for both iOS and MacCatalyst.
79+# Step 6: Check exit code
80+echo $? # Should be 0 for success
81+```
7282  
73−### Sample Projects
83+**CRITICAL**: If Step 2 shows NO test actions, the test didn't actually run even if it "completed successfully". Update your Appium test and rerun.
7484  
75−- `src/Controls/samples/Maui.Controls.Sample` - Full gallery sample with all controls and features
76−- `src/Controls/samples/Maui.Controls.Sample.Sandbox` - Empty project for testing/reproduction
77−- `src/Essentials/samples/Essentials.Sample` - Essentials API demonstrations (non-UI MAUI APIs)
78−- `src/BlazorWebView/samples/` - BlazorWebView sample applications
85+**If ANY of these checks fail, the test DID NOT complete successfully. Investigate and fix before proceeding.**
7986  
80−## Development Workflow
87+---
8188  
82−### Testing
89+## 🚨 WARNING: "Test Completed Successfully" ≠ Test Actually Worked
8390  
84−Major test projects:
85−- **Core**: `src/Core/tests/UnitTests/Core.UnitTests.csproj`
86−- **Essentials**: `src/Essentials/test/UnitTests/Essentials.UnitTests.csproj`
87−- **Controls**: `src/Controls/tests/Core.UnitTests/Controls.Core.UnitTests.csproj`
88−- **XAML**: `src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj`
91+**CRITICAL UNDERSTANDING**: The message "✅ Test completed successfully" only means:
92+- ✅ Appium test script finished running without crashing
93+- ✅ Script exit code was 0
8994  
90−Find all tests: `find . -name "*.UnitTests.csproj"`
95+**It does NOT mean**:
96+- ❌ Appium found your UI elements
97+- ❌ Buttons were clicked
98+- ❌ Navigation happened
99+- ❌ Your test scenario actually ran
91100  
92−### CI Pipelines (Azure DevOps)
101+### Example of False Success
93102  
94−When referencing or triggering CI pipelines, use these current pipeline names:
103+**What you see in output**:
104+```
105+✅ Test completed successfully
95106  
96−| Pipeline | Name | Purpose |
97−|----------|------|---------|
98−| Overall CI | `maui-pr` | Full PR validation build |
99−| Device Tests | `maui-pr-devicetests` | Helix-based device tests |
100−| UI Tests | `maui-pr-uitests` | Appium-based UI tests |
107+╔═══════════════════════════════════════════════════════════╗
108+║ Test Summary ║
109+╠═══════════════════════════════════════════════════════════╣
110+║ Platform: ANDROID ║
111+║ Device: emulator-5554 ║
112+║ Result: SUCCESS ✅ ║
113+╚═══════════════════════════════════════════════════════════╝
114+```
101115  
102−**⚠️ Old pipeline names** (e.g., `MAUI-UITests-public`, `MAUI-public`) are **outdated** and should NOT be used. Always use the names above.
116+**What actually happened**:
117+```bash
118+# Check the logs:
119+grep "no such element" CustomAgentLogsTmp/Sandbox/build-run-output.log
120+# Result: 20+ lines of "no such element" errors
103121  
104−### Investigating CI Failures
122+# The test looked for "InstructionLabel" which doesn't exist in MainPage
123+# Appium never found ANY elements
124+# Test script just gave up and exited with code 0
125+# NO ACTUAL TESTING WAS PERFORMED
126+```
105127  
106−**🚨 ALWAYS use the `azdo-build-investigator` skill when investigating CI failures or assessing merge readiness.** Its instructions direct you to invoke the `ci-analysis` skill first for the core investigation workflow, then apply MAUI-specific corrections (correct pipeline names, XHarness quirks, binlog guidance).
128+### How to Detect False Success
107129  
108−Do NOT default to manually querying AzDO APIs or rely solely on `gh pr checks` pass/fail counts.
130+**MANDATORY check after EVERY "successful" test**:
131+```bash
132+# Look for actual test actions in output
133+grep -E "Tapping|Clicking|Found element|Screenshot saved" CustomAgentLogsTmp/Sandbox/build-run-output.log
134+```
109135  
110−**When to use it:**
111−- "How does CI look?" / "Is CI green?" / "Can we merge?"
112−- "What's failing?" / "Are these known failures?"
113−- "Is this PR safe to merge?" / "Any CI concerns?"
114−- After any PR push to verify the build
136+**If grep returns NOTHING → FALSE SUCCESS**:
137+- Test didn't actually do anything
138+- Template test is looking for elements that don't exist
139+- You MUST update `CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs` to match your MainPage
140+- Rerun BuildAndRunSandbox.ps1 after updating test
115141  
116−**Verifying specific tests:** When asked "did test X pass?" or "did the new test run?", query the **actual AzDO test results** — do NOT infer whether a test ran by inspecting code attributes. Class-level traits, base class categories, and assembly-level attributes can all cause a test to run even when the method itself has no visible category. Check the evidence, not the code.
142+**If grep returns multiple lines → REAL SUCCESS**:
143+- Test found elements and interacted with them
144+- Proceed with full validation checklist
117145  
118−**Anti-pattern:** Writing ad-hoc scripts to parse AzDO build timelines. The skills handle Helix work item details, known issue cross-referencing, and test result aggregation that manual approaches miss.
146+---
119147  
120−### Gradle / Maven Dependency Failures (CFSClean)
148+## Purpose
121149  
122−The official CI build uses CFSClean network isolation which blocks `repo.maven.apache.org`. All Gradle/Maven dependencies resolve through the `dotnet-public-maven` Azure Artifacts feed.
150+Work with the Sandbox app for manual testing, PR validation, issue reproduction, and experimentation with MAUI features.
123151  
124−**If CI fails with Gradle 401 errors** like `"No local versions of package"` or `"Please provide authentication to save package from upstream"`, it means a Maven package hasn't been ingested into the feed yet. **Fix:** run `./eng/ingest-maven-deps.sh` locally to pre-populate the feed. See `src/Core/AndroidNative/settings.gradle` for details.
152+## When to Use Sandbox Testing
125153  
126−**Do NOT upgrade Gradle past 8.x** — the Android SDK's `net.android.init.gradle.kts` is incompatible with Gradle 9.x (`dotnet/android#10738`).
154+- ✅ User asks to "test this PR" (functional testing, not code review)
155+- ✅ User asks to "validate PR #XXXXX" or "validate PR #XXXXX in Sandbox"
156+- ✅ User asks to "reproduce issue #XXXXX" or "try out issue #XXXXX"
157+- ✅ User asks to "try out" or "experiment with" a feature in Sandbox
158+- ✅ PR modifies core MAUI functionality (controls, layouts, platform code)
159+- ✅ Need to manually verify a fix works on device/simulator
160+- ✅ Need to create a quick test scenario for hands-on validation
127161  
128−### Code Formatting
162+## When NOT to Use Sandbox
129163  
130−Always format code before committing:
164+- ❌ User asks to "review PR #XXXXX" → Use **pr** agent for code review
165+- ❌ User asks to "write tests" or "create automated tests" → Use **write-tests-agent**
166+- ❌ User asks to "validate the UI tests" or "verify test quality" → Review test code instead
167+- ❌ User asks to "fix issue #XXXXX" (no PR exists) → Suggest `/delegate` command
168+- ❌ PR only adds documentation (no code changes to test)
169+- ❌ PR only modifies build scripts (no functional changes)
131170  
171+## Distinction: Code Review vs. Functional Testing
172+ 
173+**Code Review** (pr-review skill):
174+- Analyzes code quality, patterns, best practices
175+- Reviews test coverage and correctness
176+- Checks for potential bugs or issues in the code itself
177+- Trigger: "review PR", "work on PR"
178+ 
179+**Functional Testing** (sandbox-agent):
180+- Builds and deploys PR to device/simulator
181+- Manually validates the fix works as expected
182+- Reproduces issues and verifies they're resolved
183+- Trigger: "test this PR", "validate PR in Sandbox", "reproduce issue"
184+ 
185+## 🚨 Critical Requirements for Android Testing
186+ 
187+**ANDROID-ONLY REQUIREMENT - appium:noReset**
188+ 
189+⚠️ **This ONLY applies to Android, NOT iOS**
190+ 
191+When testing on Android, the Appium test script **MUST** have this capability:
192+ 
193+```csharp
194+// ANDROID ONLY - Do NOT add this for iOS
195+if (PLATFORM == "android")
196+{
197+ options.AddAdditionalAppiumOption("appium:noReset", true);
198+}
199+```
200+ 
201+**Why this is critical for Android:**
202+- Without `noReset`, Appium clears app data between runs
203+- This breaks .NET MAUI's Fast Deployment mechanism on Android
204+- App crashes with: `"No assemblies found in '.../__override__/...' ... Assuming this is part of Fast Deployment. Exiting..."`
205+- The app will crash immediately on launch before any test can run
206+ 
207+**iOS does NOT need this** - iOS deployment works differently and doesn't use Fast Deployment
208+ 
209+**Where to set it:**
210+- Template: `.github/scripts/templates/RunWithAppiumTest.template.cs` (line ~68, Android section only)
211+- Active test: `CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs` (Android section only)
212+ 
213+**Platform detection is automatic** - The template automatically detects Android vs iOS from the UDID format, so you don't need to manually set the platform. The `if (PLATFORM == "android")` block will execute automatically when testing on Android.
214+ 
215+**⚠️ NEVER REMOVE THIS CAPABILITY FROM ANDROID** - All Android tests depend on it
216+ 
217+---
218+ 
219+## Core Workflow
220+ 
221+**🚨 CRITICAL RULES FOR ENTIRE WORKFLOW:**
222+- **ALWAYS use BuildAndRunSandbox.ps1 script** for building, deploying, and testing
223+- **NEVER use manual `dotnet build`, `adb`, or `xcrun` commands**
224+- **NEVER switch branches during reproduction** - stay on the current branch
225+- **ALWAYS stop and ask user if you cannot reproduce** - do not try alternative branches
226+- The script handles device detection, build, deployment, and test execution automatically
227+- See "BuildAndRunSandbox.ps1 Script" section below for full details
228+ 
229+---
230+ 
231+### Step 1: Understand Issue (DO NOT Checkout PR Unless Instructed)
232+ 
233+**⚠️ IMPORTANT**: Only checkout a PR if the user explicitly asks you to test a specific PR. For general issue reproduction, work on the current branch.
234+ 
132235 ```bash
133−dotnet format Microsoft.Maui.sln --no-restore --exclude Templates/src --exclude-diagnostics CA1822
236+# ONLY if user explicitly asks to test a PR:
237+gh pr checkout <PR_NUMBER>
134238 ```
135239  
136−## Contribution Guidelines
240+**Understand the issue thoroughly:**
241+- Read issue report or PR description
242+- Identify what bug needs to be reproduced
243+- Note affected platforms
244+- Look for reproduction steps in the issue
245+- If testing a PR: Review PR changes to understand the fix
137246  
138−### Handling Existing PRs for Assigned Issues
247+---
139248  
140−**🚨 CRITICAL REQUIREMENT: Always develop your own solution first, then compare with existing PRs.**
249+### Step 2: Create Test Scenario in Sandbox
141250  
142−1. **Develop your own solution first** - Analyze the issue independently and design your approach without looking at existing PRs
143−2. **Search for existing PRs** - After developing your solution, search for open PRs addressing the same issue
144−3. **Compare and evaluate** - Examine existing PR approaches and decide which solution better addresses the issue
145−4. **Document your decision** - In your PR description, compare your solution to existing PRs and explain why you chose your approach, including concerns with alternatives
146−5. **Improve either solution** - Whether using your solution or an existing one, enhance with better tests, code quality, error handling, or documentation
251+**Choose test scenario source (in priority order):**
147252  
148−### Auto-Generated Files (Never Commit)
253+1. **From Issue Reproduction** (Preferred)
254+ - Look for "Reproduction" or "Steps to Reproduce" in the linked issue
255+ - Use the exact scenario the user reported
256+ - This proves you're testing what the user experienced
149257  
150−These files are auto-generated and must NOT be committed:
151−- `cgmanifest.json` - Generated during CI builds
152−- `templatestrings.json` - Auto-generated localization
258+2. **From PR's UI Tests** (Alternative)
259+ - Check if PR includes files in `TestCases.HostApp/Issues/IssueXXXXX.*`
260+ - Adapt the test page code to Sandbox
261+ - Simplify if needed for manual testing
153262  
154−**For AI agents:** Always reset changes to these files before committing.
263+3. **Create Your Own** (Last Resort)
264+ - If no repro available, design scenario based on PR changes
265+ - Focus on the specific code paths modified by the fix
266+ - Keep it simple and focused
155267  
156−### PublicAPI.Unshipped.txt File Management
268+**Files to modify**:
269+- `src/Controls/samples/Controls.Sample.Sandbox/MainPage.xaml[.cs]` - UI and code for reproduction
270+- `CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs` - Appium test script (MANDATORY - see setup below)
157271  
158−When working with public API changes:
159−- **Never disable analyzers** to bypass PublicAPI.Unshipped.txt issues
160−- **Always add correct API entries** to PublicAPI.Unshipped.txt files
161−- **Use `dotnet format analyzers`** if having trouble
162−- **If files are incorrect**: Revert all changes, then add only the necessary new API entries
272+**Setting up the Appium test file (MANDATORY):**
163273  
164−### Branching
165−- `main` - For bug fixes without API changes
166−- The highest `netN.0` branch (by convention) - For new features and API changes. To find it, run `git fetch origin` then: `git for-each-ref --sort=-version:refname --count=1 --format='%(refname:lstrip=3)' refs/remotes/origin/net*.0`
274+🚨 **CRITICAL**: Update Appium test BEFORE running script. Template will give FALSE SUCCESS otherwise.
167275  
168−### Git Workflow (Copilot CLI Rules)
276+1. **Create test file**:
277+ ```bash
278+ mkdir -p CustomAgentLogsTmp/Sandbox
279+ cp .github/scripts/templates/RunWithAppiumTest.template.cs CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs
280+ ```
169281  
170−**🚨 CRITICAL Git Rules for Copilot CLI:**
282+2. **Update test to match MainPage**:
283+ - Check AutomationIds: `grep AutomationId MainPage.xaml`
284+ - Update test to use those IDs (not template defaults)
285+ - Add test logic: tap buttons, verify labels
286+ - Add Console.WriteLine markers for debugging
171287  
172−1. **NEVER commit directly to `main`** - Always create a feature branch for your work. Direct commits to `main` are strictly prohibited.
288+3. **Example**:
289+ ```bash
290+ # Check MainPage
291+ grep 'AutomationId=' MainPage.xaml
292+ # Update test: App.WaitForElement("NavigateButton");
293+ ```
173294  
174−2. **When amending an existing PR, work on the PR's branch directly** - Do NOT create a separate branch off a PR branch. The PR branch already IS a feature branch. Creating a new branch off it means CI won't run on the original PR, defeating the purpose. Use `gh pr checkout` to switch to the PR branch, make your changes, commit, **then** ask before pushing so the user can review locally first.
295+**Checklist**:
296+- ✅ Add AutomationIds to MainPage.xaml elements
297+- ✅ Update RunWithAppiumTest.cs to match
298+- ✅ Add SANDBOX markers for debugging
175299  
176−3. **Do NOT rebase, squash, or force-push** unless explicitly requested by the user. These operations rewrite git history and can cause problems for other contributors. Default behavior should be regular commits and pushes.
300+**🚨 CRITICAL - Document Your Test Scenario:**
177301  
178−**Safe Git Workflow:**
302+You MUST include in your final report:
303+- ✅ **Source**: Where did the test scenario come from? (issue reproduction / PR UITest / custom)
304+- ✅ **Why**: Why did you choose that source? (e.g., "Issue #XXXXX provides detailed repro steps")
305+- ✅ **What**: What specific actions does your test perform? (e.g., "Tap button → verify label changes to 'Success'")
306+- ✅ **Expected**: What behavior should occur? (from issue description or PR changes)
307+ 
308+Without this documentation, user cannot verify you tested the right thing.
309+ 
310+---
311+ 
312+### Step 3: Test WITH PR Fix
313+ 
314+**Platform Selection Decision Tree:**
315+ 
316+Follow this flowchart in order - stop at the first match:
317+ 
318+```
319+┌─────────────────────────────────────────────────────────────────┐
320+│ 1. Does PR title have platform tag? [Android], [iOS], etc. │
321+│ YES → Test that platform ONLY │
322+│ NO → Continue to step 2 │
323+├─────────────────────────────────────────────────────────────────┤
324+│ 2. Are ALL modified files in platform-specific paths? │
325+│ (Platform/Android/, Platform/iOS/, *.Android.cs, etc.) │
326+│ YES → Test that platform ONLY │
327+│ NO → Continue to step 3 │
328+├─────────────────────────────────────────────────────────────────┤
329+│ 3. Does issue report mention a specific platform? │
330+│ YES (one platform) → Test that platform ONLY │
331+│ YES (multiple) → Test Android + iOS │
332+│ NO → Continue to step 4 │
333+├─────────────────────────────────────────────────────────────────┤
334+│ 4. Is this high-risk cross-platform code? │
335+│ (Controls/, Core/, layout, navigation, critical controls) │
336+│ YES → Test Android + iOS │
337+│ NO → Test Android ONLY (default - faster) │
338+└─────────────────────────────────────────────────────────────────┘
339+```
340+ 
341+**Platform-specific path indicators:**
342+- `Platform/Android/` or `Platform/iOS/` → Platform-specific
343+- Files with `.Android.`, `.iOS.`, `.MacCatalyst.` in name → Platform-specific
344+- `Controls/`, `Core/` without platform subfolders → Cross-platform
345+ 
346+**Hard rule:** Never test more than 2 platforms unless user explicitly requests it.
347+ 
348+**Run Test on Specific iOS Device/Version:**
349+ 
350+When user requests a specific iOS version or device:
351+ 
352+1. **Find the UDID for that device/version combination**:
353+ ```bash
354+ # Example: Find iPhone Xs with iOS 18.5
355+ UDID=$(xcrun simctl list devices available --json | jq -r '
356+ .devices
357+ | to_entries
358+ | map(select(.key | contains("iOS-18-5")))
359+ | map(.value)
360+ | flatten
361+ | map(select(.name == "iPhone Xs"))
362+ | first
363+ | .udid
364+ ')
365+
366+ echo "Found UDID: $UDID"
367+ ```
368+ 
369+2. **Pass the UDID to the script**:
370+ ```bash
371+ pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform ios -DeviceUdid "$UDID"
372+ ```
373+ 
374+**Examples:**
375+- **"Run on iOS 18.5"** → Find iPhone Xs with iOS 18.5, get UDID, pass to script
376+- **"Run on iPhone 15"** → Find iPhone 15 (any iOS), get UDID, pass to script
377+- **"Run on iPhone 16 Pro with iOS 18.0"** → Find iPhone 16 Pro with iOS 18.0, get UDID, pass to script
378+ 
379+---
380+ 
381+## How the Template Works
382+ 
383+**The template ALWAYS does the same thing:**
384+ 
385+1. ✅ Verifies app launched successfully (WaitForElement)
386+2. ✅ Optionally runs automated UI tests (if you add them)
387+3. ✅ Exits WITHOUT closing the app (stays running for manual validation)
388+ 
389+**Usage:**
179390 ```bash
180−# Create a feature branch (NEVER work directly on main)
181−git checkout -b feature/issue-12345
391+# Copy the template
392+cp .github/scripts/templates/RunWithAppiumTest.template.cs CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs
182393  
183−# Make commits normally
184−git add .
185−git commit -m "Fix: Description of the change"
394+# OPTIONAL: Add automated test logic in the TEST LOGIC section
395+# If you don't add test logic, it just verifies launch and exits
186396  
187−# Push to remote (for new branches)
188−git push -u origin feature/issue-12345
397+# Run the script
398+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform ios
399+```
189400  
190−# For subsequent pushes on the same branch
191−git push
401+**Result:**
402+- App launches and stays running
403+- You can manually validate in the simulator
404+- Test script exits without closing the app
405+ 
406+---
407+ 
408+## 🚨 CRITICAL: BuildAndRunSandbox.ps1 Script - ONLY Way to Deploy Sandbox
409+ 
410+**YOU MUST ALWAYS USE THIS SCRIPT. NEVER USE MANUAL `dotnet build`, `adb`, or `xcrun` COMMANDS.**
411+ 
412+### Script Location
413+`.github/scripts/BuildAndRunSandbox.ps1`
414+ 
415+### Basic Usage
416+```powershell
417+# Android
418+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform Android
419+ 
420+# iOS (auto-detects device)
421+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform iOS
422+ 
423+# iOS with specific device
424+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform iOS -DeviceUdid "YOUR-DEVICE-UDID"
192425 ```
193426  
194−**When asked to update an existing PR:**
427+### What the Script Does Automatically
428+- ✅ **Device detection and boot** - Finds and boots simulator/emulator
429+- ✅ **UDID extraction** - Sets DEVICE_UDID environment variable
430+- ✅ **Fresh app build** - Builds Sandbox project for target platform
431+- ✅ **App deployment** - Installs and launches app
432+- ✅ **Appium server management** - Starts/stops Appium automatically
433+- ✅ **Log capture** - Saves device and Appium logs to `CustomAgentLogsTmp/Sandbox/`
434+- ✅ **Test execution** - Runs your Appium test script
435+ 
436+### Requirements Before Running
437+Copy and update test file (see Step 2 above). Template looks for "InstructionLabel" which doesn't exist - update first!
438+ 
439+**🚨 POST-TEST VALIDATION (MANDATORY):**
440+ 
441+After script completes, run Rule 4 validation checklist (see above). If ANY check fails: investigate, fix, rerun.
442+ 
443+**Key reminders**:
444+- HTTP 200 = element found, NOT test completed
445+- If no test actions in logs = FALSE SUCCESS
446+- If Appium can't find initial element = app crashed or AutomationIds wrong
447+ 
448+---
449+ 
450+### 📝 Note for User
451+ 
452+**Test scenario is ready in Sandbox for manual verification.**
453+ 
454+**To verify bug reproduction (optional):**
195455 ```bash
196−# Check out the PR branch directly (do NOT create a new branch off it)
197−gh pr checkout 12345
456+# 1. Revert the PR fix files
457+git checkout main -- [list specific fix files from PR]
198458  
199−# Make fixes and commit to the PR branch
200−git add .
201−git commit -m "Fix: Description of the change"
459+# 2. Rerun test - bug should appear
460+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform [android|ios]
461+ 
462+# 3. Restore fix
463+git checkout HEAD -- [fix files]
464+ 
465+# 4. Rerun test - bug should be gone
466+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform [android|ios]
202467 ```
203−1. **STOP and ask the user** before pushing: "Changes are committed locally. Would you like me to push these changes to the PR?"
204−2. Exception: If the user's instructions explicitly include pushing, proceed without asking.
205468  
206−### Documentation
207−- Update XML documentation for public APIs
208−- Follow existing code documentation patterns
209−- Update relevant docs in `docs/` folder when needed
469+This proves the test scenario correctly reproduces the bug.
210470  
211−### Opening PRs
471+---
212472  
213−All PRs are required to have this at the top of the description:
473+## 🔄 Iterative Testing Workflow (MANDATORY PROCESS)
214474  
475+**🚨 CRITICAL**: This is THE workflow for Sandbox testing. Do NOT use manual `adb`/`xcrun` commands to bypass it.
476+ 
477+### The Required Loop
478+ 
215479 ```
216−<!-- Please let the below note in for people that find this PR -->
217−> [!NOTE]
218−> Are you waiting for the changes in this PR to be merged?
219−> It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you!
480+┌─────────────────────────────────────────────────────────────┐
481+│ 1. Update MainPage.xaml[.cs] with your test scenario │
482+│ - Add UI elements for reproduction │
483+│ - Add AutomationIds to all interactive elements │
484+│ - Add Console.WriteLine markers for debugging │
485+├─────────────────────────────────────────────────────────────┤
486+│ 2. Update Appium test to match your MainPage │
487+│ CustomAgentLogsTmp/Sandbox/RunWithAppiumTest.cs │
488+│ - Update element locators to match AutomationIds │
489+│ - Add test logic (tap buttons, verify labels) │
490+├─────────────────────────────────────────────────────────────┤
491+│ 3. Run BuildAndRunSandbox.ps1 │
492+│ pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform X │
493+├─────────────────────────────────────────────────────────────┤
494+│ 4. Validate results using SYSTEMATIC CHECKLIST │
495+│ - Step 1: Check for errors/exceptions │
496+│ - Step 2: Verify test actions (Tapping, etc.) │
497+│ - Step 3: Verify "Test completed" │
498+│ - Step 4: Check device logs for SANDBOX markers │
499+│ - Step 5-6: Screenshots and exit code │
500+├─────────────────────────────────────────────────────────────┤
501+│ 5. Did ALL validation checks pass? │
502+│ YES → Report success with summary (go to step 8) │
503+│ NO → Continue to step 6 │
504+├─────────────────────────────────────────────────────────────┤
505+│ 6. Investigate failure from captured logs │
506+│ - Read CustomAgentLogsTmp/Sandbox/android-device.log │
507+│ - Read CustomAgentLogsTmp/Sandbox/build-run-output.log │
508+│ - Identify root cause (element not found? crash?) │
509+├─────────────────────────────────────────────────────────────┤
510+│ 7. Fix the issue and LOOP BACK TO STEP 3 │
511+│ - Update MainPage if UI/code issue │
512+│ - Update RunWithAppiumTest.cs if test issue │
513+│ - Update both if AutomationId mismatch │
514+│ - Max 3 iterations before reporting as blocked │
515+├─────────────────────────────────────────────────────────────┤
516+│ 8. Report comprehensive summary to user │
517+│ - Test scenario source and justification │
518+│ - Validation results │
519+│ - Verdict (success/partial/issues/blocked) │
520+└─────────────────────────────────────────────────────────────┘
220521 ```
221522  
222−Always put that at the top, without the block quotes. Without it, users will NOT be able to try the PR and your work will have been in vain!
523+### ❌ What NOT To Do
223524  
525+**Never use manual commands during testing**:
526+- ❌ `adb logcat`, `adb shell`, `adb install`
527+- ❌ `xcrun simctl spawn`, `xcrun simctl install`
528+- ❌ `dotnet build`, `dotnet run`
224529  
530+**Why**: Script already captured everything. Manual commands show CURRENT state, not test execution state.
225531  
226−## Custom Agents and Skills
532+**✅ Correct**: Edit files → Rerun `BuildAndRunSandbox.ps1`
227533  
228−The repository includes specialized custom agents and reusable skills for specific tasks.
534+### ✅ Correct Iteration Example
229535  
230−### Skills vs Agents
536+**Most common case - Test fails to find element**:
537+```bash
538+# 1. Check what went wrong
539+grep "no such element" CustomAgentLogsTmp/Sandbox/build-run-output.log
231540  
232−| Aspect | Skills | Agents |
233−|--------|--------|--------|
234−| **Invoke** | `/skill-name` or direct request | Delegate to agent |
235−| **Output** | Analysis, recommendations | Actions, changes applied |
236−| **Interaction** | Interactive discussion | Autonomous workflow |
237−| **Example** | `/learn-from-pr` → recommendations | learn-from-pr agent → applies changes |
541+# 2. Check what DOES exist in MainPage
542+grep AutomationId src/Controls/samples/Controls.Sample.Sandbox/MainPage.xaml
238543  
239−### Available Custom Agents
544+# 3. Fix MainPage: Add AutomationIds
545+# Edit MainPage.xaml: <Button AutomationId="NavigateButton" ...
240546  
241−1. **pr** - Sequential 4-phase workflow for reviewing and working on PRs
242− - **Use when**: A PR already exists and needs review or work, OR an issue needs a fix
243− - **Capabilities**: PR review, test verification, fix exploration, alternative comparison
244− - **Trigger phrases**: "review PR #XXXXX", "work on PR #XXXXX", "fix issue #XXXXX", "continue PR #XXXXX"
245− - **Do NOT use for**: Just running tests manually → Use `sandbox-agent`
547+# 4. Fix test: Update to match
548+# Edit RunWithAppiumTest.cs: App.WaitForElement("NavigateButton");
246549  
247−2. **write-tests-agent** - Agent for writing tests. Determines test type (UI vs XAML) and invokes the appropriate skill (`write-ui-tests`, `write-xaml-tests`)
248− - **Use when**: Creating new tests for issues or PRs
249− - **Capabilities**: Test type determination (UI and XAML), skill invocation, test verification
250− - **Trigger phrases**: "write tests for #XXXXX", "create tests", "add test coverage"
550+# 5. Rerun
551+pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform android
552+```
251553  
252−3. **sandbox-agent** - Specialized agent for working with the Sandbox app for testing, validation, and experimentation
253− - **Use when**: User wants to manually test PR functionality or reproduce issues
254− - **Capabilities**: Sandbox app setup, Appium-based manual testing, PR functional validation
255− - **Trigger phrases**: "test this PR", "validate PR #XXXXX in Sandbox", "reproduce issue #XXXXX", "try out in Sandbox"
256− - **Do NOT use for**: Code review (use pr agent), writing automated tests (use write-tests-agent)
554+**When validation passes**: Report success with comprehensive summary
257555  
258−4. **learn-from-pr** - Extracts lessons from PRs and applies improvements to the repository
259− - **Use when**: After complex PR, want to improve instruction files/skills based on lessons learned
260− - **Capabilities**: Analyzes PR, identifies failure modes, applies improvements to instruction files, skills, code comments
261− - **Trigger phrases**: "learn from PR #XXXXX and apply improvements", "improve repo based on what we learned", "update skills based on PR"
262− - **Output**: Applied changes to instruction files, skills, architecture docs, code comments
263− - **Do NOT use for**: Analysis only without applying changes → Use `/learn-from-pr` skill instead
556+### When to Stop Iterating
264557  
265−5. **release-readiness-agent** - Assesses ship-readiness for a .NET MAUI release branch — both **SR** (`release/*-srN`) and **Preview** (`release/*-previewN`)
266− - **Use when**: A release (SR or Preview) is approaching ship date and you need a synthesized verdict with WorkIQ/MCP enrichment on top of the deterministic report — **or** for a portfolio question across all active releases ("status on releases", "what needs attention across releases") where the user may not know which releases exist
267− - **Capabilities**: Resolves the branch (SR or Preview) from natural language, picks the right script (`Get-ReleaseReadiness.ps1` for SR, `Get-PreviewReadiness.ps1` for Preview), enriches `rejected-from-sr` candidates with WorkIQ context (SR lane), patches `UNKNOWN` ship-check rows via MCP (`maestro_default_channels`, `maestro_builds`), presents an overall verdict
268− - **Trigger phrases**: "is SR7 ready to ship", "release readiness for release/10.0.1xx-sr7", "survey the SR8 branch", "how does net11 preview6 look", "is preview6 ready to cut", "release readiness for release/11.0.1xx-preview6" — **plus portfolio / cross-release questions with no specific release named**: "give me a status on releases", "release status overview", "what's the status across all releases", "what needs attention across releases", "what's next for MAUI releases"
269− - **Output**: Verdict (Ready / Conditionally Ready / Not Ready) + per-candidate classification (SR) or per-section table (Preview) + actionable next steps
270− - **Do NOT use for**: Programmatic / scripted consumers that just need the raw JSON — use the `release-readiness` skill directly. Reviewing a single PR (use **pr**). Running tests manually (use **sandbox-agent**).
558+- ✅ **All validation checks pass** → Report success with detailed summary
559+- ❌ **Max 3 iterations reached** → **STOP and report**: "I wasn't able to reproduce the issue. What should I try next?"
560+- ❌ **Build fails repeatedly** → **STOP and report**: "I wasn't able to reproduce the issue due to build failures. What should I try next?"
561+- ❌ **Root cause unclear after log analysis** → **STOP and report**: "I wasn't able to reproduce the issue. What should I try next?"
562+- ❌ **Issue appears to be PR bug, not test** → **STOP and report findings to user**: "I wasn't able to reproduce the issue - it appears there may be an issue with [details]. What should I try next?"
563+- ❌ **Cannot reproduce the issue** → **STOP immediately**: "I wasn't able to reproduce the issue. What should I try next?"
271564  
272−### Reusable Skills
565+**CRITICAL**: When you cannot reproduce or hit blockers, **PAUSE and ask the user**. Do NOT:
566+- ❌ Switch to a different branch (e.g., `git checkout main`)
567+- ❌ Try alternative approaches without asking first
568+- ❌ Change the workflow significantly without user guidance
273569  
274−Skills are modular capabilities that can be invoked directly or used by agents. Located in `.github/skills/`:
570+### Mental Model: The Script is Your Robot
275571  
276−#### User-Facing Skills
572+BuildAndRunSandbox.ps1 handles: build → deploy → capture logs → run test → report
277573  
278−1. **pr-review** (`.github/skills/pr-review/SKILL.md`)
279− - **Purpose**: End-to-end PR review orchestrator — 3 phases: pr-preflight, try-fix, pr-report. Gate runs separately before this skill via Review-PR.ps1.
280− - **Trigger phrases**: "review PR #XXXXX", "work on PR #XXXXX", "fix issue #XXXXX", "continue PR #XXXXX"
281− - **Capabilities**: Multi-model fix exploration, alternative comparison, PR review recommendation
282− - **Do NOT use for**: Just running tests manually → Use `sandbox-agent`
283− - **Phase instructions** (in `.github/pr-review/`):
284− - `pr-preflight.md` — Context gathering from issue/PR
285− - `pr-report.md` — Final recommendation
286− - **Phase skill**: `try-fix` — Multi-model fix exploration
287− - **Note**: Gate (test verification) runs as a script step in `Review-PR.ps1` before this skill is invoked. Gate result is passed in the prompt.
574+**Your workflow**: Edit files → Run script → Read logs → Fix issues → Repeat
288575  
289−2. **issue-triage** (`.github/skills/issue-triage/SKILL.md`)
290− - **Purpose**: Query and triage open issues that need milestones, labels, or investigation
291− - **Trigger phrases**: "find issues to triage", "show me old Android issues", "what issues need attention"
292− - **Scripts**: `init-triage-session.ps1`, `query-issues.ps1`, `record-triage.ps1`
576+---
293577  
294−2. **find-reviewable-pr** (`.github/skills/find-reviewable-pr/SKILL.md`)
295− - **Purpose**: Finds open PRs in dotnet/maui and dotnet/docs-maui that need review
296− - **Trigger phrases**: "find PRs to review", "show milestoned PRs", "find partner PRs"
297− - **Scripts**: `query-reviewable-prs.ps1`
298− - **Categories**: P/0, milestoned, partner, community, recent, docs-maui
578+## Output Format
299579  
300−3. **pr-finalize** (`.github/skills/pr-finalize/SKILL.md`)
301− - **Purpose**: Verifies PR title and description match actual implementation, AND performs code review for best practices before merge.
302− - **Trigger phrases**: "finalize PR #XXXXX", "check PR description for #XXXXX", "review commit message"
303− - **Used by**: Before merging any PR, when description may be stale
304− - **Note**: Does NOT require agent involvement or session markdown - works on any PR
305− - **🚨 CRITICAL**: NEVER use `--approve` or `--request-changes` - only post comments. Approval is a human decision.
580+Provide a concise test summary:
306581  
307−4. **code-review** (`.github/skills/code-review/SKILL.md`)
308− - **Purpose**: Reviews PR code changes for correctness, safety, and consistency with MAUI conventions. Walks through a MAUI-specific checklist covering handler lifecycle, platform code, safe area, threading, public API, and test patterns.
309− - **Trigger phrases**: "review code for PR #XXXXX", "code review PR #XXXXX", "review this PR's code"
310− - **Note**: Standalone skill — uses independence-first assessment (reads code before PR description to avoid anchoring bias). Can be used by any agent or invoked directly.
311− - **🚨 CRITICAL**: NEVER use `--approve` or `--request-changes` — only post comments. Approval is a human decision.
582+```markdown
583+## PR Testing Summary
312584  
313−5. **learn-from-pr** (`.github/skills/learn-from-pr/SKILL.md`)
314− - **Purpose**: Analyzes completed PR to identify repository improvements (analysis only, no changes applied)
315− - **Trigger phrases**: "what can we learn from PR #XXXXX?", "how can we improve agents based on PR #XXXXX?"
316− - **Used by**: After complex PRs, when agent struggled to find solution
317− - **Output**: Prioritized recommendations for instruction files, skills, code comments
318− - **Note**: For applying changes automatically, use the learn-from-pr agent instead
585+**PR**: #XXXXX - [Title]
586+**Platform Tested**: Android/iOS
587+**Issue**: [Brief description]
319588  
320−6. **write-ui-tests** (`.github/skills/write-ui-tests/SKILL.md`)
321− - **Purpose**: Creates UI tests for GitHub issues and verifies they reproduce the bug
322− - **Trigger phrases**: "write UI tests for #XXXXX", "create UI test for issue", "add UI test coverage"
323− - **Output**: Test files that fail without fix, pass with fix
589+---
324590  
325−7. **write-xaml-tests** (`.github/skills/write-xaml-tests/SKILL.md`)
326− - **Purpose**: Creates XAML unit tests for XAML parsing, compilation, and source generation
327− - **Trigger phrases**: "write XAML tests for #XXXXX", "test XamlC behavior", "reproduce XAML parsing bug"
328− - **Output**: Test files for Controls.Xaml.UnitTests
591+### Test Scenario Setup
329592  
330−9. **verify-tests-fail-without-fix** (`.github/skills/verify-tests-fail-without-fix/SKILL.md`)
331− - **Purpose**: Verifies tests catch the bug before fix and pass with fix. Auto-detects test type (UI, device, unit, XAML) and dispatches to the appropriate runner.
332− - **Two modes**: Verify failure only (test creation) or full verification (test + fix)
333− - **Used by**: After creating tests, before considering PR complete
593+**🚨 REQUIRED - Source of Test Scenario**:
594+- **Source**: [From issue reproduction / From PR UITest / Custom scenario]
595+- **Why this source**: [e.g., "Issue #XXXXX provides detailed repro steps" / "PR includes UITest that demonstrates the fix" / "No repro available, created scenario based on PR code changes"]
596+- **Link to source**: [URL to issue comment with repro, or path to UITest file]
334597  
335−10. **run-integration-tests** (`.github/skills/run-integration-tests/SKILL.md`)
336− - **Purpose**: Build, pack, and run .NET MAUI integration tests locally
337− - **Trigger phrases**: "run integration tests", "test templates locally", "run macOSTemplates tests", "run RunOniOS tests"
338− - **Categories**: Build, WindowsTemplates, macOSTemplates, Blazor, MultiProject, Samples, AOT, RunOnAndroid, RunOniOS
339− - **Note**: **ALWAYS use this skill** instead of manual `dotnet test` commands for integration tests
598+**What was tested**:
599+- [Specific actions taken - e.g., "Tap 'Toggle RTL' button, then tap 'Show Dialog' button"]
600+- [UI elements involved - e.g., "Button with AutomationId='ToggleButton', Dialog with Label"]
601+- [Expected behavior - e.g., "Dialog should appear with correct RTL padding on label"]
340602  
341−11. **dependency-flow** (`.github/skills/dependency-flow/SKILL.md`)
342− - **Purpose**: MAUI-specific dependency flow rules, channel conventions, and feed lookup workflows
343− - **Trigger phrases**: "feeds for .NET MAUI X.Y.Z", "where is MAUI build", "promote build to public feed", "what channels is MAUI on", "subscription health for MAUI"
344− - **Wraps**: `maestro-cli` skill (from `dotnet-dnceng@dotnet-arcade-skills` plugin) and maestro MCP tools
345− - **Note**: Provides MAUI-specific guardrails on top of core Maestro/darc operations — channel naming, safety deny-list, input validation, and prompt injection defense
603+---
346604  
347−12. **release-readiness** (`.github/skills/release-readiness/SKILL.md`)
348− - **Purpose**: Deterministic ship-readiness engine for .NET MAUI release branches — both **SR** (`release/*-srN`) and **Preview** (`release/*-previewN`). Surveys CI, computes what's actually shipping, classifies open regressions, identifies port candidates and rejected backports
349− - **Trigger phrases**: "release readiness for SRN", "is SR7 ready to ship", "survey the SR branch", "release readiness for preview6", "how does preview6 look (deterministic)", "status across all releases" (reads the live `[Release Readiness]` tracker issues by body marker — no survey re-run needed)
350− - **Scripts**: `Get-ReleaseReadiness.ps1` (SR lane), `Get-PreviewReadiness.ps1` (Preview lane), `Find-ReleaseReadinessTrackers.ps1` (tracker discovery)
351− - **Output**: JSON + Markdown report, list of source PRs, classification of regression issues (in-sr-active, rejected-from-sr, no-fix-yet, etc.)
352− - **Note**: Deterministic and reproducible — no MCP, no LLM judgment. Use **this skill directly** when you need raw output for a script, dashboard, cron job, or programmatic consumer. For natural-language verdict synthesis with WorkIQ enrichment, use the **`release-readiness-agent`** instead.
605+### Test Results WITH PR Fix
353606  
354−#### Internal Skills (Used by Agents)
607+**Observed Behavior**:
608+- [What happened when running the test]
609+- [Appium test results]
610+- [Relevant log excerpts]
355611  
356−13. **try-fix** (`.github/skills/try-fix/SKILL.md`)
357− - **Purpose**: Proposes ONE independent fix approach, applies it, tests, records result with failure analysis, then reverts
358− - **Used by**: pr agent Phase 3 (Fix phase) - rarely invoked directly by users
359− - **Behavior**: Reads prior attempts to learn from failures. Max 5 attempts per session.
360− - **Output**: Updates session markdown with attempt results and failure analysis
612+**Screenshots**: [Reference if taken, but not for validation]
361613  
362−### Using Custom Agents
614+---
363615  
364−**Delegation Policy**: When user request matches agent trigger phrases, **ALWAYS delegate to the appropriate agent immediately**. Do not ask for permission or explain alternatives unless the request is ambiguous.
616+### Verdict
365617  
366−**Examples of correct delegation**:
367−- User: "Review PR #12345" → Immediately invoke **pr** agent
368−- User: "Test this PR" → Immediately invoke **sandbox-agent**
369−- User: "Fix issue #67890" (no PR exists) → Suggest using `/delegate` command
370−- User: "Write tests for issue #12345" → Immediately invoke **write-tests-agent**
371−- User: "Is SR7 ready to ship?" → Immediately invoke **release-readiness-agent**
372−- User: "How does net11 preview6 look?" → Immediately invoke **release-readiness-agent**
373−- User: "Give me a status on releases / what needs attention across releases?" → Immediately invoke **release-readiness-agent** (portfolio mode — it enumerates active releases by reading the `[Release Readiness]` tracker issues; don't ask "which release?")
374−- User: "Give me the raw release-readiness JSON for SR8" → Use the **release-readiness** skill directly (no enrichment needed)
618+✅ **FIX VALIDATED** - Test scenario completes successfully, expected behavior observed
619+OR
620+⚠️ **PARTIAL** - Fix appears to work but [note any concerns]
621+OR
622+❌ **ISSUES FOUND** - [Specific problems encountered]
623+OR
624+🚫 **CANNOT TEST** - [Build failures, setup issues, etc.]
375625  
376−**When NOT to delegate**:
377−- User asks "What does PR #12345 do?" → Informational query, handle yourself
378−- User asks "How do I test PRs?" → Documentation query, handle yourself
379−- User has follow-up questions after agent completes → Continue the conversation yourself
626+---
627+ 
628+### Notes for User
629+- Test scenario is set up in Sandbox and ready for manual verification if needed
630+- To verify bug reproduction without fix, revert PR changes: `git checkout main -- [fix files]`
631+- Then rerun: `pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform [android|ios]`
632+```
633+ 
634+---
635+ 
636+## Best Practices
637+ 
638+1. **Use issue reproduction when available** - Most reliable test scenario
639+2. **Adapt PR's UITests if no repro** - They're already designed to test the fix
640+3. **Validate programmatically, reference visually** - Use Appium element queries for validation, screenshots only for additional context
641+4. **Use colored backgrounds** - Makes layout issues visible
642+5. **Add console markers** - Easy to grep logs
643+6. **Test multiple iterations** - Race conditions need multiple runs (3-5 times)
644+7. **Leave Sandbox as-is** - User will iterate on it after your testing
645+8. **Document your test scenario thoroughly** - Include source (issue/UITest/custom), why you chose it, specific actions, and expected behavior so user can verify
646+ 
647+**Screenshot Usage**:
648+- ✅ Take screenshots for **context and reference** (e.g., showing layout before/after)
649+- ✅ Include in report if they provide **additional insight** beyond what logs show
650+- ❌ Do NOT rely on screenshots as **primary validation** - use Appium element queries and log analysis
651+- ❌ Do NOT take screenshots just to show "it works" - validation should come from test assertions
652+ 
653+---
654+ 
655+## Log Capture and Review
656+ 
657+### Where Logs Are Saved
658+ 
659+After running BuildAndRunSandbox.ps1, all logs are in `CustomAgentLogsTmp/Sandbox/`:
660+ 
661+1. **Android**: `CustomAgentLogsTmp/Sandbox/android-device.log`
662+2. **iOS**: `CustomAgentLogsTmp/Sandbox/ios-device.log`
663+3. **Appium**: `CustomAgentLogsTmp/Sandbox/appium.log`
664+ 
665+### Viewing Logs
666+ 
667+```bash
668+# View device logs
669+cat CustomAgentLogsTmp/Sandbox/android-device.log
670+# or
671+cat CustomAgentLogsTmp/Sandbox/ios-device.log
672+ 
673+# Search for specific output
674+grep "TEST OUTPUT" CustomAgentLogsTmp/Sandbox/android-device.log
675+ 
676+# View Appium logs
677+cat CustomAgentLogsTmp/Sandbox/appium.log
678+```
679+ 
680+### 📝 Adding Debug Logging to Your Test Scenario
681+ 
682+**Use `Console.WriteLine` for logging** - it works on all platforms.
683+ 
684+```csharp
685+// Use a unique prefix for easy grep
686+Console.WriteLine("SANDBOX: Button clicked");
687+Console.WriteLine($"SANDBOX: Value is {myValue}");
688+```
689+ 
690+**Searching logs:**
691+```bash
692+grep "SANDBOX" CustomAgentLogsTmp/Sandbox/android-device.log
693+grep "SANDBOX" CustomAgentLogsTmp/Sandbox/ios-device.log
694+grep "SANDBOX" CustomAgentLogsTmp/Sandbox/catalyst-device.log
695+```
696+ 
697+---
698+ 
699+## 🚨 ABSOLUTE RULE: BuildAndRunSandbox.ps1 is THE ONLY Deployment Method
700+ 
701+**THIS IS MANDATORY. NOT A SUGGESTION.**
702+ 
703+❌ If typing `adb`/`xcrun` commands during testing → STOP. You're violating the workflow.
704+ 
705+**Why**: Manual commands show CURRENT state, not test execution state. Script already captured correct logs during test.
706+ 
707+**❌ NEVER during testing**: `adb logcat`, `adb install`, `adb shell`, `xcrun simctl install/spawn`, `dotnet build/run`
708+ 
709+**✅ ONLY exception**: Finding/booting specific iOS device BEFORE running script (`xcrun simctl list/boot`)
710+ 
711+**Correct workflow**:
712+1. Edit files (MainPage, RunWithAppiumTest.cs)
713+2. Run: `pwsh .github/scripts/BuildAndRunSandbox.ps1 -Platform X`
714+3. Analyze logs in `CustomAgentLogsTmp/Sandbox/` (android-device.log, appium.log)
715+4. Fix issues, rerun script
716+ 
717+**Expected logs**: `android-device.log` or `ios-device.log`, `appium.log`, `RunWithAppiumTest.cs`, optional screenshots
718+ 
719+---
720+ 
721+## Troubleshooting & Recovery
722+ 
723+**Retry up to 3 times before reporting as blocked.** After each failure: analyze logs → fix → rerun script.
724+ 
725+### Common Issues
726+ 
727+| Issue | Recovery | Max Retries |
728+|-------|----------|-------------|
729+| Build error | Check SDK version, `dotnet tool restore` | 2 |
730+| App crash | Check stack trace in device log, fix code/XAML | 3 |
731+| Element not found | Verify AutomationIds match, check app loaded | 2 |
732+| Fast Deployment (Android) | Add `appium:noReset` capability | 1 |
733+| XAML parse error | Verify event handler exists in code-behind | 2 |
734+ 
735+### Element Not Found Debugging
736+ 
737+🚨 If Appium can't find initial element, app is NOT running correctly.
738+ 
739+**Check**:
740+```bash
741+# Look for crashes
742+grep -i "FATAL\|crash\|exception" CustomAgentLogsTmp/Sandbox/android-device.log | tail -20
743+ 
744+# Verify app launched
745+grep "SANDBOX.*MainPage" CustomAgentLogsTmp/Sandbox/android-device.log
746+```
747+ 
748+**Root causes**: App crashed, XAML parse error, AutomationId mismatch, Android Fast Deployment
749+ 
750+### When to Stop & Report
751+- ✅ **Continue**: Minor warnings, non-critical timeouts, platform differences
752+- ❌ **Stop and ask user**: Can't checkout PR, build fails after max retries, SDK mismatch, root cause unclear, cannot reproduce issue
753+ 
754+**When blocked, ALWAYS report to user with this format**:
755+```markdown
756+I wasn't able to reproduce the issue. Here's what I tried:
757+ 
758+1. [What I attempted]
759+2. [Issues encountered]
760+3. [Current state of reproduction attempt]
761+ 
762+What should I try next?
763+```
764+ 
765+**DO NOT** try alternative approaches without asking first. **DO NOT** switch branches.
766+ 
767+### Test Shows Unexpected Behavior
768+**Action**: Document and report
769+ 
770+```markdown
771+⚠️ Unexpected behavior during testing
772+ 
773+**What I expected**: [Based on issue description]
774+ 
775+**What I observed**: [Actual behavior]
776+ 
777+**Test scenario**: [What was tested]
778+ 
779+**Logs**: [Relevant excerpts]
780+ 
781+**Question for user**: Is this expected behavior, or does this indicate an issue?
782+```
783+ 
784+---
785+ 
786+## Common Mistakes to Avoid
787+ 
788+- ❌ Using TestCases.HostApp for manual PR validation (use Sandbox)
789+- ❌ Manual build/deploy commands instead of BuildAndRunSandbox.ps1
790+- ❌ Testing only one platform when PR affects multiple
791+- ❌ Using screenshots for validation (use Appium element queries)
792+- ❌ Creating test scenario without checking issue for reproduction steps
793+- ❌ Ignoring PR's existing UITests when available
794+- ❌ Cleaning up or reverting Sandbox changes (user will iterate on it)
795+ 
796+**Testing Tips**:
797+- For layout bugs: Use `element.GetRect()` to measure positions
798+- For SafeArea PRs: Measure child content position, not parent size
799+- Add `Console.WriteLine("SANDBOX: ...")` markers for debugging
800+ 
801+---
802+ 
803+## Appendix: Cleanup (Only When User Requests)
804+ 
805+⚠️ **DO NOT clean up after testing** - Leave Sandbox as-is so user can iterate on it.
806+ 
807+Only use these commands if the **user explicitly requests cleanup**:
808+ 
809+### Sandbox App Cleanup (User Request Only)
810+```bash
811+# Revert all changes to Sandbox app
812+git checkout -- src/Controls/samples/Controls.Sample.Sandbox/
813+```
814+ 
815+### Sandbox Test Files Cleanup (User Request Only)
816+```bash
817+# Remove Appium test directory (gitignored)
818+rm -rf CustomAgentLogsTmp/Sandbox/
819+```
820+ 
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack