Thanks for your interest. This document describes how to set up, contribute, and what reviewers look for.
git clone https://github.com/carterscode/GamerGuardian.git
cd GamerGuardian
dotnet build
dotnet test
src\GamerGuardian\bin\Debug\net8.0-windows10.0.22000.0\GamerGuardian.exe --show-settingsFor the installer build and CI workflow details, see docs/wiki/Build-from-source.md.
main is protected — you cannot push to it directly. The flow:
- Branch off
main:git checkout -b feat/something-descriptive. Usefeat/,fix/,chore/,ci/,docs/prefixes. - Commit your changes with descriptive messages (see Commit messages below).
- Push the branch:
git push -u origin feat/something-descriptive. - Open a pull request:
gh pr create --base main. - CI runs automatically —
build,Analyze (csharp),Analyze (actions). All three must pass before merge. - Self-merge once green:
gh pr merge --merge --delete-branch(no required approvals for the solo-dev workflow).
Conventional Commits format. The first line is <type>: <imperative summary> under 72 chars.
Common types:
feat:— new functionality (new monitor, UI feature, CLI flag)fix:— bug fixchore:— maintenance, refactors with no behavior changeci:— workflow / build pipeline changesdocs:— wiki, README, commentsperf:— performance improvementsui:— UI/UX changes
Multi-line bodies are encouraged for non-trivial changes — explain why, not what. Example:
fix(services): stop UAC spam when Windows reverts a service change
Symptom: enabling auto-apply on a service Windows refuses to actually
disable (DoSvc / Delivery Optimization is the trigger case) caused a
UAC prompt every 30 s forever.
MonitorService now trips the auto-apply circuit breaker for a setting
whose verify keeps failing (logged as [CIRCUIT]). Drift still surfaces
as a notification.
- Follow the existing patterns. The codebase is small and consistent.
<Nullable>enable</Nullable>is on. Don't introduce?types if you can avoid them.<TreatWarningsAsErrors>true</TreatWarningsAsErrors>is on. Build warnings break CI.- Default to no comments. Only comment the why when the what is obvious from the code. See examples in
Monitors/HagsMonitor.csfor the conventional level of commenting. - C# expression-bodied members and pattern-matching are encouraged where they read naturally.
- Don't introduce abstractions speculatively. Three similar lines is better than a premature framework.
The canonical example is src/GamerGuardian/Monitors/HagsMonitor.cs — about 30 lines.
A new monitor needs:
- A class implementing
IMonitoredSettinginsrc/GamerGuardian/Monitors/. - Registration in
App.xaml.csin thefixedMonitorsarray. - A row in
SettingsWindow.xaml.csLoadGlobals(or the equivalent for your tab). - A
MechanismForandVerifyCommandForentry insrc/GamerGuardian/Services/SettingDocs.cs. - A test in
tests/GamerGuardian.Tests/(see Tests below).
If the new monitor writes to HKLM, route it through ElevatedRegistry so it shares the existing UAC-prompt behavior.
For the Windows services tab, just append to ServiceCatalog.All in src/GamerGuardian/Services/ServiceCatalog.cs. No code change required elsewhere — WindowsServiceMonitor is registered once per catalog entry by App.xaml.cs.
If the service is one Windows actively protects (re-enables via WaaSMedicSvc etc.), set RecommendedTarget: ServiceTargetState.Manual rather than Disabled, or omit it from the catalog entirely. See docs/wiki/Architecture-rationale.md for the WU-protection background.
We use xUnit. The test project lives at tests/GamerGuardian.Tests/.
Run all tests:
dotnet testCI runs the same on every PR.
When you add or change behavior:
- Pure logic (catalogs, mappings, parsers, lookup tables) — add a unit test covering the new behavior.
- Native API wrappers (anything in
Native/orWindowsServiceController) — add a "doesn't throw on bad input" test if practical. Full coverage isn't expected since these wrap Windows APIs that aren't easily mockable. - UI — manual verification on a dev-build artifact is the current standard. UI test automation is on the roadmap.
- Bug fixes — add a regression test if the bug is reproducible from a unit test.
The general rule: it's fine to merge without a test if the change can't be reasonably unit-tested (a UI tweak, a workflow change, a doc update). It's not fine to merge without a test if the change touches a class that is unit-tested already.
- Bug reports / feature requests: GitHub Issues. Search first; include
--testoutput and yourchanges.logif relevant. - Security vulnerabilities: see SECURITY.md. Do not open a public issue.
- Questions: also fine in Issues; tag with
question.
- The change is scoped to one concern.
- New behavior has a test if reasonably testable.
- No new compiler warnings.
- Commit messages explain why.
- No secrets in the diff (GitHub push protection will catch most, but double-check).
- Touched files have consistent style with the surrounding code.
- For new dependencies: justified, well-maintained, license-compatible (MIT-friendly).
By contributing you agree your contributions are licensed under the MIT License, the same license the project uses.