Contributing¶
Thanks for helping map paid Microsoft security capabilities to real configuration.
Ways to contribute¶
- New checks (highest value) — YAML under
checks/<workload>/ - Catalog updates — service plan / SKU mappings in
catalog/ - Collectors — read-only Graph / Azure data sources
- Docs and samples — clearer MSP/consultant workflows
- Bug fixes and tests
Development setup¶
This is the same pip + venv path CI uses:
Quality checks¶
These match CI (.github/workflows/ci.yml). Run them before opening a PR:
ruff check src tests
ruff format --check src tests
pytest tests/ -m "not browser" --cov=licenselens --cov-fail-under=72
licenselens scan --dry-run -o reports
licenselens scan --dry-run exits 0 or 1 when the demo catalog has gaps or
partial findings; both are expected. Any other exit code is a failure.
Optional checks¶
Not required for every PR:
- Playwright report tests:
python -m playwright install --with-deps chromiumthenpytest tests/test_report_browser.py --browser chromium - Pester suites (Windows): adapter contracts in
powershell/LicenseLens.Collectors/tests/and installer tests inpackaging/windows/tests/ - Regenerated reference docs:
python scripts/generate_reference_docs.py - Docs site:
mkdocs build --strictorscripts/docs-check.sh(that script invokesuv runfor mkdocs and codespell)
Adding a check¶
Follow Adding a check.
Every enabled check is either activation or hygiene (tier: in YAML).
The hygiene pack is frozen for MSP convenience:
- Hygiene checks are accepted only when they (a) map an existing SCuBA baseline row that has no local check, or (b) fix a false result.
- Activation checks need the adding-a-check justification: which SKU/plan unlocks the capability, what gap means operationally, and why it matters.
Minimum bar for a new check PR:
- Valid YAML with stable
idandtier: activationortier: hygiene required_capabilitiespointing at catalog entries- Clear remediation and at least one reference URL
- Unit test or fixture when collector logic is included
- No write/remediation API calls
Code style¶
- Python 3.12+, type hints preferred
rufffor lint and format- Do not commit secrets, tenant IDs from real customers, or unredacted reports
Public docs and releases¶
This repo is a standalone product. Keep GitHub-facing material presentation-neutral:
- Do not mention talks, slide decks, event-tied milestones, or event names in README, CHANGELOG, docs, CLI help, release notes, or commit messages meant for GitHub.
- Describe features in product terms (quick start, default packs, demo command).
- Local planning tools (OpenSpec changes, editor agent config) stay out of the
repo — see
.gitignore.
Pull requests¶
- One logical change per PR
- Link related issues
- Include dry-run output snippet when behavior changes
Code of conduct¶
Be respectful. See CODE_OF_CONDUCT.md.