microsoft / microsoft/microsoft-ui-reactor

[Bug] SourceSnippetSanityTests anchors repo-root on CWD, not AppContext.BaseDirectory — can validate a sibling worktree

Open Beginner friendly
#1,031 0 comments 0 reactions 0 assignees View on GitHub
bug needs-triage
Dominant language
C#
Stars
646
Forks
54
Avg merge
1d 3h
Merged PRs (30d)
84

Description

### What happened?

`tests/Reactor.DocPipeline.Tests/SourceSnippetSanityTests.cs:27` anchors its repo-root walk on the **process current directory**:

```csharp
private static string FindRepoRoot()
{
var dir = Directory.GetCurrentDirectory(); // <-- process CWD
while (dir is not null)
{
if (File.Exists(Path.Combine(dir, "Reactor.slnx")) || Directory.Exists(Path.Combine(dir, ".git")))
return dir;
dir = Path.GetDirectoryName(dir);
}
throw new InvalidOperationException("Reactor repo root not found from test cwd.");
}
```

Every other copy in the repo anchors on `AppContext.BaseDirectory` — the test assembly's own location, which is necessarily inside the tree that built it:

| file | anchor |
|---|---|
| `tests/Reactor.AppTests/Tests/Spec051DevtoolsPackageE2ETests.cs:131` | `AppContext.BaseDirectory` |
| `tests/Reactor.IntegrationTests/Packaging/CreateTemplateTests.cs:367` | `AppContext.BaseDirectory` |
| `tests/Reactor.DocPipeline.Tests/VersionSubstitutionTests.cs:213` | `AppContext.BaseDirectory` |
| `tests/Reactor.Tests/TemplateMetadataTests.cs:194` | `AppContext.BaseDirectory` |
| `tests/Reactor.Tests/VersionSingleSourceTests.cs:210` | `AppContext.BaseDirectory` |
| `src/Reactor.Cli/Pack/RepoRootFinder.cs:13` (the shared one) | `AppContext.BaseDirectory` |
| **`tests/Reactor.DocPipeline.Tests/SourceSnippetSanityTests.cs:27`** | **`Directory.GetCurrentDirectory()`** |

**Why it matters here specifically.** `AGENTS.md` tells contributors *"Work in a clean worktree, not `main`: `git worktree add …`"*, so a developer machine is expected to have **several valid checkouts of this repo at once**. A CWD-anchored walk finds whichever tree the process happens to be standing in. If that is a *sibling worktree*, `src/Reactor/Hooks/UseMemoCells.cs` exists there too, `ExtractFromSource` succeeds, and the test **passes green having validated a different tree than the one it was built from**. The repo's own recommended workflow is the precondition for the failure.

**Severity: low / latent**, and I'd rather state the mitigations than overclaim:

- The test runner normally sets CWD to the assembly output directory, so today this usually coincides with `AppContext.BaseDirectory`. I have not observed it fire.
- It `throw`s when no root is found, so the "wrong machine entirely" case fails **loudly** rather than silently.
- The silent-wrong-answer case needs CWD to sit inside *another checkout of this same repo* — real on a worktree-using dev box or a mutation/merge harness that drives a scratch worktree, but not on a clean CI runner.

The general hazard is worth recording regardless: `Set-Location`/`cd` in a driver script does **not** update the .NET process working directory, so managed relative-path resolution and shell relative-path resolution can silently disagree. Verified on this machine:

```
after Set-Location to :
Get-Location : C:\...\Temp\pA-4cefdf
[Environment]::CurrentDirectory : C:\...\
Set-Location updated CurrentDirectory? -> False
[IO.Path]::GetFullPath('probe.txt') : C:\...\\probe.txt <- not pA
```

Note the failure is silent **only when the same relative path is valid under both roots** — otherwise it throws. Parallel worktrees of one repo guarantee that condition, which is what makes this shape worth avoiding rather than merely noting.

### Steps to reproduce

1. `git worktree add ../wt-b origin/main` so two valid checkouts exist.
2. Build `Reactor.DocPipeline.Tests` in worktree A.
3. Run the test host with the process working directory set inside worktree B.
4. `Extracts_demo_region_from_UseMemoCells` passes — against **B's** `src/Reactor/Hooks/UseMemoCells.cs`, not A's.

### Suggested fix

One line — switch the anchor, matching the five siblings:

```csharp
var dir = AppContext.BaseDirectory;
```

Better, since a shared implementation already exists: have these tests call `RepoRootFinder.FindRepoRoot()` (`src/Reactor.Cli/Pack/RepoRootFinder.cs`) instead of each re-deriving it. Six near-identical private copies is how one of them drifted. That consolidation is the actual fix; the anchor change is the stopgap.

### Reactor version / commit

`8d3db0a271b0e5bc8043782e63c3cd8d6e6b5e89` — but the affected file is unmodified by that branch and is present on `main`.

### Platform

x64

### .NET SDK version

10.0.302

### Windows version

Windows 11 Enterprise Insider Preview (build 26310)

### Windows App SDK version

N/A — `Reactor.DocPipeline.Tests` is a headless test project with no Windows App SDK dependency.

### Logs / stack trace

N/A — no failure observed; this is a latent anchoring inconsistency found by inspection after verifying the underlying path-resolution divergence, not a reproduced red test.

### Confirmation

- [x] I have searched existing issues and this isn't a duplicate.
- [x] This bug reproduces against the current `main` branch (the file is untouched by my branch).

Contributor guide

Open the contributing guide

Research direction

Start at tests/Reactor.DocPipeline.Tests/SourceSnippetSanityTests.cs:27 and compare its FindRepoRoot anchor with AppContext.BaseDirectory and src/Reactor.Cli/Pack/RepoRootFinder.cs. Run the affected SourceSnippetSanityTests, including Extracts_demo_region_from_UseMemoCells, with separate worktrees; done means the test resolves files from the assembly's own checkout rather than the process CWD.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.