pr-local-validation
Skill240 starsChanged 27 days agoMITView on GitHub
Validate a pull request on real hardware: clone its exact head commit into a disposable checkout, build it, run the live-write test suite for the selected Godot versions, build Release, and publish a scoped result back on the pull request. Triggers: validate a PR locally, run the live tests for a PR, local PR validation, run the live-write suite, validate PR on hardware, pr-local-validation
In this repository5 other files it gives its agents.
- .github/copilot-instructions.mdCopilot instructions
- adversarial-reviewSkill
- gdextension-hygieneSkill
- issue-triageSkill
- pr-feedback-loopSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 29
Add -DryRun first to print the plan without touching anything.
- Very specific: line 119
Run with -DryRun and show the user the resolved head SHA and run directory.
- Very specific: line 120
Run for real with -AllowLiveWrites.
- Very specific: line 121
Read validation-manifest.json.
- Very specific: line 122
If the status is not pass, read the failing leg's run-summary.json and logs, and state precisely which stage degraded and why.
- Distinctive: line 129
Do not claim live coverage from a hosted CI run.
- Distinctive: line 130
Do not drop an engine from the matrix to get a green result.
- Distinctive: line 131
Do not add support-list coverage inference, concurrency machinery or another grading framework in response to review feedback.
- Distinctive: line 133
Do not edit the candidate checkout to make a test pass.
- Distinctive: line 134
Do not delete the run directory before reporting — it is the evidence.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
PR Local Validation Skill
You are the repo-local pr-local-validation skill. Your job is to take a pull request and produce honest, reproducible evidence for an exact commit, one actual SDK and the selected engines on real hardware. A passing run is not approval of the entire PR support matrix.
This exists because GitHub Actions cannot prove what this repo most needs proven. Hosted runners have no GDK, no Xbox sandbox, and cannot form a PlayFab Party P2P mesh, so the hosted gates deliberately skip the live tier. A green PR is therefore not evidence that a GDK bump works. This skill closes that gap on a self-hosted machine.
The one command
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\tools\validate_pr_local.ps1 `
-PullRequest <number> -AllowLiveWritesAdd -DryRun first to print the plan without touching anything. Add -NoComment to keep
the result local. Add -GodotVersion <v>[,<v>] to narrow the engine matrix, or
-GdkVersion <v> to pin a specific supported GDK.
tools\validate_pr_local.ps1 is the whole workflow. Do not reimplement its steps by hand,
and do not substitute a narrower run for it when the user asked for live validation.
Core rules
- Validate the head commit, never the merge result. The script fetches
refs/pull/<n>/headand checks out the exact SHA detached. A later head is outside this result's scope. Do not describe an older run as validating it. - Validate a fresh clone, never the working tree. The run clones into a private run
directory. A dirty local tree, a stale
build\, or leftover mirrored addons would make the result meaningless. - Never source logic from the candidate PR. The wrapper, its modules, and its policy
come from the trusted checkout you launched from. Only
tools\run_all_tests.ps1,.github\godot-versions.json, and.github\gdk-versions.jsonare read from the candidate, because those are the things under test. - Run every supported engine by default. The engine list comes from the candidate
checkout's
.github\godot-versions.json, not from a hard-coded list and not from whatever Godot is installed on the machine. Each engine is downloaded fresh and hash-verified against the manifest pin. - Narrow only on request, and never hide it.
-GodotVersion <v>[,<v>]restricts the matrix. Suggest it when the user is time-boxed and the PR is a GDK-only bump — the native SDK surface does not branch on engine version — but do not choose it silently. A narrowed run can pass (exit 0). Name the selected engines and list unselected versions as scope notes, not failures or missing requested work. - One GDK per run; pin it when the PR is about the GDK. Nothing in the local build
path reads
.github\gdk-versions.json— CI injects anms-gdkoverride, butcmake --preset defaultjust resolves the registry baseline. So the manifestdefaultis informational, not a validation target without a pin. Use-GdkVersion <v>to write the same override CI uses and build a specific supported SDK; if vcpkg then restores something else the run fails hard. Pinning edits the checkout, so say so when reporting. There is no GDK matrix: a second SDK means a full reconfigure plus the whole Godot matrix again. - A green exit code is not a pass.
run_all_tests.ps1can exit 0 while covering nothing: an unfiltered PlayFab Multiplayer run may pass with zero scenarios, and a live GUT host may report every test pending.Get-EngineLegVerdictdowngrades those toincomplete. Reportincompleteasincomplete. - Prove the SDK identity from the built tree. The GDK edition comes from
build\vcpkg_installed\x64-windows\include\grdk.h(_GRDK_EDITION) and the package version from that tree'sshare\ms-gdk\vcpkg.spdx.json. Membership in.github\gdk-versions.jsonproves nothing about what vcpkg actually restored, and the999999fallback ingdk_edition.his never acceptable as proof. - Restore the sandbox. The run captures the current Xbox sandbox before switching to
the test sandbox and restores it in a
finally. If restoration fails it leavesSANDBOX-RESTORE.txtin the run directory — surface that loudly, the machine is left in a test sandbox. - Live writes land in one fixed title. PlayFab title
10D176with the non-secret smoke profile. Never point this at another title, and never run the provisioning script as part of validation — that is a separate, explicit operation.
Preconditions to confirm before running
- The PR is same-repository, not a fork. The script refuses
isCrossRepositoryPRs before it fetches anything, and that refusal has no override: a run executes candidate build and test code with the operator's account, credentials, and Xbox identity, and the fresh clone is workspace isolation rather than a security sandbox. For a fork contribution, review the diff and push it to a branch in this repository first. - The machine has the GDK, Visual Studio build tools, and
XblPCSandbox.exe. gh auth statussucceeds, with write access if a comment will be posted.- The shell is elevated only if the machine is not already in the test sandbox, because switching restarts Xbox Live Auth Manager. Do not elevate otherwise — the candidate's build and tests should not run with more privilege than they need.
- Better still, the machine is already in the test sandbox with a test account signed
into the Xbox app. Switching mid-run signs the Xbox app out, and the GDK live tiers
need a signed-in account that only an interactive UI can provide — so a mid-run switch
usually yields
no_default_userlegs. Tell the user to switch and sign in first; the script then skips the switch, the restore, and the elevation requirement. - The nightly
playfab-liveworkflow is not mid-run, and no other local run is in progress. Nothing enforces this: the script has no lock, because a machine-local one could not serialize against GitHub Actions or another machine anyway. Overlapping runs share one PlayFab title and fight over the machine's sandbox, so coordinate by hand.
Reading the result
| Exit code | Status | Meaning |
| 0 | pass | The selected engines ran live writes, required stages covered real tests, both builds passed and the sandbox was restored. |
| 2 | incomplete | Requested work was not completed or covered nothing. Deliberately unselected versions do not cause this. |
| 1 | fail / error | A stage failed, or the run could not be interpreted at all. |
Artifacts land under %LOCALAPPDATA%\godot-gdk-pr-validation\pr-<n>-<sha12>-<timestamp>\:
report.md, validation-manifest.json, per-engine results\<version>\run-summary.json,
and logs\. Quote the manifest, not your memory of the console output.
Loop
- Confirm the preconditions above; stop and ask if any are unmet.
- Run with
-DryRunand show the user the resolved head SHA and run directory. - Run for real with
-AllowLiveWrites. - Read
validation-manifest.json. Do not summarize from scrollback. - If the status is not
pass, read the failing leg'srun-summary.jsonand logs, and state precisely which stage degraded and why. - Confirm the posted PR comment matches the manifest, including the coverage gaps and the "Not covered by this run" caveats.
Do not
- Do not claim live coverage from a hosted CI run.
- Do not drop an engine from the matrix to get a green result.
- Do not add support-list coverage inference, concurrency machinery or another grading framework in response to review feedback. A broader guarantee needs a separate, approved requirement.
- Do not edit the candidate checkout to make a test pass; fix it on the PR branch instead.
- Do not delete the run directory before reporting — it is the evidence.
Output format
- Scope — PR, head SHA, engines, title and sandbox used.
- Result — overall status plus the per-engine table.
- Failures — each failing stage with its reason.
- Coverage gaps — anything reported
incomplete, stated plainly. - Not covered — console targets, packaging/submission, other PlayFab titles.
- Follow-up — what a human still has to decide.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

