microsoft / microsoft/microsoft-ui-reactor
Nothing gates the CI-repro build command against `ci.yml` — three docs now duplicate it
- Dominant language
- C#
- Stars
- 646
- Forks
- 54
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 84
Description
## Summary
[#1165](https://github.com/microsoft/microsoft-ui-reactor/pull/1165) fixed #1163 by correcting the pre-push build command, and in doing so brought a third copy of it into the tree. The CI-repro command now appears verbatim in three places:
| File | Audience | Depth |
|---|---|---|
| `.github/PULL_REQUEST_TEMPLATE.md` | outside contributor | one line + short rationale |
| `CONTRIBUTING.md` (*Reproducing the CI build gate*) | contributor deep-dive | full explanation |
| `AGENTS.md` (Field notes → Building & running tests) | agents | full + measurement |
The layering is deliberate — different audiences need different depth, and the template defers to `CONTRIBUTING.md`. The problem is that **nothing gates the three against `ci.yml` or against each other.**
## Why this is worth a gate rather than a comment
This is the exact failure mode that produced #1163. That issue existed *because* `AGENTS.md` and `.github/PULL_REQUEST_TEMPLATE.md` disagreed about the same command, and the disagreement went unnoticed because no check compared them. #1165 resolved the disagreement by hand — but by adding a third copy, it made the same drift structurally *more* likely next time, not less.
Concretely, if the `build-solution` job in `.github/workflows/ci.yml` ever changes (a new flag, a different target, a split step), all three docs silently become wrong, and the first signal is a contributor pushing a PR that fails a gate their documented command said they had already cleared.
Line-number drift already bit this once: #1163 cited `ci.yml:342` for a step that had moved to `:329` before the issue was filed. #1165 replaced line references with job/step-name anchors, which fixes *that* axis — but not the command-text axis.
## Suggested fix
A unit test in `tests/Reactor.Tests/Docs/` that parses the `Restore` and `Build` steps of the `build-solution` job out of `.github/workflows/ci.yml`, and asserts the documented command in each of the three files agrees with them.
There is direct precedent for reading repo files from a unit test: `tests/Reactor.Tests/Docs/SwallowedErrorAuditTests.cs:33` does exactly this (`const string AuditPath = "docs/specs/044/swallowed-error-audit.md"`), and the repo already runs several drift gates in this style — the swallowed-error ledger, the `reactor.api.txt` two-copy sync, and the ReactorGallery search-index byte-compare.
The oracle should be non-vacuous: it must fail if the CI step changes and the docs don't, so the test needs to derive the expected string from `ci.yml` rather than hard-coding it alongside the docs. A hard-coded expectation would restate the docs and pass forever.
## Notes
- Low priority — the three copies agree today, verified byte-identical on `main` as of `c9225296`.
- Worth considering whether the template's copy should shrink to a pointer at `CONTRIBUTING.md` instead, reducing three copies to two. That trades a little contributor convenience (the command is no longer inline where it's read) for one less drift surface; the gate is probably the better fix either way.
- Filed as a follow-up from the #1163 / #1165 work rather than folded in, since it's a testing change and #1165 was deliberately markdown-only.
Contributor guide
Research direction
Start with tests/Reactor.Tests/Docs/SwallowedErrorAuditTests.cs:33 for the existing repo-file reading pattern, then inspect the Restore and Build steps of the build-solution job in .github/workflows/ci.yml and the command copies in .github/PULL_REQUEST_TEMPLATE.md, CONTRIBUTING.md, and AGENTS.md. Run the relevant Reactor.Tests project tests. Done means the gate derives its expected command from ci.yml and fails when any documented copy drifts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, github-actions
- Domain
- ci-cd, documentation, testing
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100