Skip to content

Commit 40ecd82

Browse files
committed
Sprint 3: Documentation & Developer Experience\n\n- Add docs/DEVELOPMENT.md — comprehensive local setup, API reference, testing guide, release checklist\n- Add docs/COVERAGE.md — per-module coverage baseline (core: ~81%, total: ~51%)\n- Add SECURITY.md (root level) — full OWASP compliance table, security model, supported versions\n- Add hypothesis>=6.100 and pytest-mock>=3.14 to [dev] extras in pyproject.toml\n- Add __all__ to: analytics, config, deps, elevation, locale, marketplace, ratings\n- Update .github/ISSUE_TEMPLATE/new_tweak.md — add source_url field, --validate checklist, full HKEY names\n- Update .github/ISSUE_TEMPLATE/performance_issue.md — RegiLattice-specific (benchmark, --stats)\n- Include .github/workflows/powershell.yml — PSScriptAnalyzer lint for .ps1/.psm1 files\n\n17511 tests passing · ruff clean · mypy --strict clean"
1 parent 7f968a4 commit 40ecd82

14 files changed

Lines changed: 699 additions & 36 deletions

File tree

.github/ISSUE_TEMPLATE/new_tweak.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,50 +8,57 @@ assignees: ''
88

99
## Tweak Details
1010

11-
- **ID (kebab-case):** `example-disable-feature`
11+
- **ID (kebab-case):** `category-disable-feature` (prefix must match a slug in `copilot-instructions.md`)
1212
- **Label:** Disable Feature
13-
- **Category:** (existing category or new one)
14-
- **Needs admin:** Yes / No
15-
- **Corp safe:** Yes / No
13+
- **Category:** (must be one of the 69 existing categories, or propose a new one)
14+
- **Needs admin:** Yes / No (HKLM = Yes, HKCU-only = No)
15+
- **Corp safe:** Yes / No (HKCU-only and non-policy = Yes)
16+
- **Min build:** 0 (or specific Windows build, e.g. 22000 for Windows 11)
17+
- **Source URL:** <https://learn.microsoft.com/>... (KB article or doc reference)
1618

1719
## Registry Keys
1820

1921
```
2022
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\...
21-
ValueName (REG_DWORD) = 1
23+
ValueName (REG_DWORD) = 1 # applied state
24+
(absent or 0) # default / removed state
2225
```
2326

2427
## What It Does
2528

2629
Description of what the tweak changes and why a user would want it.
30+
Include `Default: 0. Recommended: 1.` in the description field.
2731

2832
## Apply Logic
2933

3034
```python
31-
SESSION.set_dword(r"HKLM\SOFTWARE\Policies\...", "ValueName", 1)
35+
SESSION.set_dword(r"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\...", "ValueName", 1)
3236
```
3337

3438
## Remove Logic (revert to default)
3539

3640
```python
37-
SESSION.delete_value(r"HKLM\SOFTWARE\Policies\...", "ValueName")
41+
SESSION.delete_value(r"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\...", "ValueName")
3842
```
3943

4044
## Detect Logic
4145

4246
```python
43-
SESSION.read_dword(r"HKLM\SOFTWARE\Policies\...", "ValueName") == 1
47+
SESSION.read_dword(r"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\...", "ValueName") == 1
4448
```
4549

4650
## References
4751

4852
- Microsoft docs link
49-
- Related Group Policy setting
50-
- Windows version requirements (10/11, specific builds)
53+
- Related Group Policy Object (GPO) setting name
54+
- Windows version and build requirements
5155

5256
## Checklist
5357

54-
- [ ] I've verified the registry path exists on a fresh Windows install
55-
- [ ] I've tested apply + remove manually via `reg add` / `reg delete`
56-
- [ ] The tweak is reversible (remove restores the default state)
57-
- [ ] The ID doesn't conflict with existing tweaks (`python -m regilattice --list`)
58+
- [ ] Registry path verified on a clean Windows install
59+
- [ ] Tested apply + remove manually (`reg add` / `reg delete` or `regedit`)
60+
- [ ] Tweak is reversible — remove restores exact default state
61+
- [ ] ID is globally unique: `python -m regilattice --list` shows no conflicts
62+
- [ ] Smoke test passes: `python -m pytest tests/test_tweaks_smoke.py -x --tb=short`
63+
- [ ] Lint passes: `python -m ruff check regilattice/ tests/`
64+
- [ ] Validate passes: `python -m regilattice --validate`
Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: Performance Issue
3-
about: Report a performance problem (slow execution, high memory, etc.)
3+
about: Report a performance problem (slow startup, slow detection, high memory, etc.)
44
title: "[Perf] "
55
labels: performance
66
assignees: ''
@@ -10,36 +10,45 @@ assignees: ''
1010

1111
Brief description of the performance issue.
1212

13-
## Project / Component
13+
## Component
1414

15-
Which project and operation is slow? (e.g., `Scripts.DupDetector / file scan`)
15+
Which operation is slow? (e.g., `all_tweaks()` load, `status_map()` detection, GUI startup, `--list`)
1616

1717
## Observed Performance
1818

19-
- **Operation:** (e.g., scanning 10,000 files)
20-
- **Time taken:** (e.g., 45 seconds)
21-
- **Expected time:** (e.g., ~5 seconds)
22-
- **Memory used:** (e.g., 2 GB peak)
19+
- **Operation:** (e.g., `status_map()` over 1 292 tweaks)
20+
- **Time taken:** (e.g., 12 seconds)
21+
- **Expected time:** (e.g., ~2 seconds)
22+
- **Memory used:** (e.g., 150 MB peak)
2323

2424
## Profiling Data
2525

2626
<details>
2727
<summary>Profile output (optional)</summary>
2828

2929
```
30-
Paste cProfile / line_profiler / memory_profiler output here
30+
# Run: python -m cProfile -s cumtime -m regilattice --list
31+
Paste cProfile / line_profiler output here
3132
```
3233

3334
</details>
3435

36+
## Benchmark Result
37+
38+
```powershell
39+
# Run: python -m pytest tests/test_benchmarks.py -v
40+
Paste benchmark output here
41+
```
42+
3543
## Environment
3644

37-
- **OS:** (e.g., Windows 11 / Ubuntu 24.04)
45+
- **OS:** Windows 11 (build ...)
3846
- **CPU:** (e.g., Intel Core i7-12700K)
3947
- **RAM:** (e.g., 32 GB)
40-
- **Storage:** (e.g., NVMe SSD / HDD)
41-
- **Python:** (e.g., 3.12.3)
48+
- **Python:** (`python -m regilattice --version` / `python --version`)
49+
- **RegiLattice:** (version from `--version`)
50+
- **Tweaks loaded:** (number from `--stats`)
4251

4352
## Additional Context
4453

45-
Dataset size, file types, specific flags used, etc.
54+
Any relevant flags used, specific category or tweak subset, etc.

.github/workflows/powershell.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ name: PSScriptAnalyzer
1111

1212
on:
1313
push:
14-
branches: [ "main" ]
14+
branches: ["main"]
1515
pull_request:
16-
branches: [ "main" ]
16+
branches: ["main"]
1717
schedule:
18-
- cron: '43 13 * * 5'
18+
- cron: "43 13 * * 5"
1919

2020
permissions:
2121
contents: read

SECURITY.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Security Policy
2+
3+
This document describes the security policy for **RegiLattice** and how to
4+
report security vulnerabilities responsibly.
5+
6+
---
7+
8+
## Supported Versions
9+
10+
| Version | Supported |
11+
|---------|-----------|
12+
| 1.0.x (latest) | ✅ Active security fixes |
13+
| < 1.0 | ❌ No longer supported |
14+
15+
---
16+
17+
## Reporting a Vulnerability
18+
19+
**Do NOT create a public GitHub issue for security vulnerabilities.**
20+
21+
To report a security concern:
22+
23+
1. Open a [GitHub Security Advisory](https://github.com/RajwanYair/RegiLattice/security/advisories/new) (preferred — private disclosure).
24+
2. Alternatively, email the maintainer with the subject line `[SECURITY] RegiLattice - <short description>`.
25+
26+
Please include:
27+
28+
- A clear description of the vulnerability
29+
- Steps to reproduce the issue
30+
- The potential impact and affected versions
31+
- Any suggested remediation or patches
32+
33+
You will receive an acknowledgement within **72 hours** and a full response
34+
within **7 days**.
35+
36+
---
37+
38+
## Security Model
39+
40+
RegiLattice modifies the Windows registry. This carries inherent risk:
41+
42+
| Risk | Mitigation |
43+
|------|-----------|
44+
| Irreversible registry changes | `RegistrySession.backup()` called before every write |
45+
| Privilege escalation | UAC prompt shown before any HKLM write; `assert_admin()` gate |
46+
| Corporate policy violations | `corpguard.py` detects domain/AAD/VPN/GPO/Intune; `corp_safe` flag per tweak |
47+
| Plugin code execution | Plugins loaded from `~/.regilattice/plugins/` only; path escapes rejected |
48+
| Supply-chain injection | Zero runtime dependencies; stdlib only |
49+
50+
---
51+
52+
## Secure Coding Practices
53+
54+
All contributors are expected to follow these practices:
55+
56+
### No Hardcoded Credentials
57+
58+
Never commit passwords, API keys, tokens, or proxy credentials. Use environment
59+
variables or the system keyring.
60+
61+
### No Hardcoded Paths
62+
63+
Use `Path(__file__).parent.resolve()` or `Path.home()` for all paths.
64+
Never hardcode `C:\Users\...`.
65+
66+
### Input Validation
67+
68+
Validate all user-supplied tweak IDs, registry paths, and file paths at
69+
the entry points (`cli.py`, `gui.py`). Reject inputs with `..` path
70+
traversal sequences.
71+
72+
### Parameterised Commands
73+
74+
Never concatenate user input into shell command strings. All `subprocess`
75+
calls use list arguments, not `shell=True`.
76+
77+
### Least Privilege
78+
79+
- Request admin (UAC) only when performing HKLM writes.
80+
- `corp_safe=True` tweaks touch only `HKCU` — no admin required.
81+
- Never request `SeDebugPrivilege` or `SeTcbPrivilege`.
82+
83+
### No Secrets in Version Control
84+
85+
`.env` files, `.regilattice.toml` with credentials, and all `*.key` / `*.pem`
86+
files are listed in `.gitignore`.
87+
88+
---
89+
90+
## OWASP Compliance Checklist
91+
92+
| OWASP Category | Status |
93+
|---|---|
94+
| Broken Access Control |`assert_admin()` + `corp_guard()` gates |
95+
| Cryptographic Failures | ✅ No encryption used; no secrets stored |
96+
| Injection (command) | ✅ All subprocess calls use list args |
97+
| Injection (path traversal) | ✅ Plugin paths validated; no `..` allowed |
98+
| Insecure Design | ✅ Backup-before-write, dry-run mode |
99+
| Security Misconfiguration | ✅ No external services; no default credentials |
100+
| Vulnerable Components | ✅ Zero runtime deps; Dependabot enabled |
101+
| Authentication Failures | N/A — local desktop tool, no auth |
102+
| Software Integrity Failures | ✅ Hatchling build; pinned CI actions |
103+
| Security Logging |`RegistrySession.log()` records all writes |
104+
| SSRF | N/A — no outbound HTTP at runtime |
105+
106+
---
107+
108+
## Changelog
109+
110+
Security-relevant changes are documented in [CHANGELOG.md](CHANGELOG.md)
111+
and tagged with `[security]`.

docs/COVERAGE.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# RegiLattice — Coverage Report
2+
3+
> Per-module test coverage baseline. Last measured: 2026-03-08 · v1.0.1
4+
> Command: `python -m pytest tests/ --cov=regilattice --cov-report=term-missing`
5+
6+
---
7+
8+
## Summary
9+
10+
| Scope | Coverage |
11+
|---|---|
12+
| **Core modules (non-tweak)** | ~81 % average |
13+
| **Tweak modules (apply/remove/detect fns)** | ~49 % average (intentionally limited — registry calls are not exercised in CI) |
14+
| **Overall total** | ~51 % |
15+
16+
The low overall percentage is dominated by the 69 tweak category modules, where
17+
the `_apply_*` / `_remove_*` / `_detect_*` functions touch real registry keys
18+
and are intentionally **not** invoked in automated tests. All tweak signatures,
19+
IDs, and `detect_fn` callability are verified via `test_tweaks_smoke.py`.
20+
21+
---
22+
23+
## Core Module Coverage
24+
25+
| Module | Statements | Missed | Coverage | Notes |
26+
|---|---|---|---|---|
27+
| `__init__.py` | 5 | 0 | **100 %** ||
28+
| `analytics.py` | 61 | 0 | **100 %** ||
29+
| `config.py` | 50 | 5 | **90 %** | tomllib fallback path (Python < 3.11) |
30+
| `corpguard.py` | 252 | 62 | **75 %** | VPN / SCCM detection paths |
31+
| `deps.py` | 73 | 0 | **100 %** ||
32+
| `elevation.py` | 44 | 2 | **95 %** | Non-Windows uid path |
33+
| `gui.py` | 1096 | 955 | **13 %** | 🔴 Highest priority — needs GUI test harness |
34+
| `gui_dialogs.py` | 171 | 76 | **56 %** | Dialog show/interact paths |
35+
| `gui_theme.py` | 97 | 2 | **98 %** ||
36+
| `gui_tooltip.py` | 97 | 25 | **74 %** | `Tooltip.show()` visual paths |
37+
| `gui_widgets.py` | 241 | 138 | **43 %** | 🔴 Widget event handlers |
38+
| `hwinfo.py` | 280 | 5 | **98 %** ||
39+
| `locale.py` | 28 | 0 | **100 %** ||
40+
| `marketplace.py` | 75 | 4 | **95 %** ||
41+
| `menu.py` | 166 | 11 | **93 %** ||
42+
| `ratings.py` | 60 | 2 | **97 %** ||
43+
| `registry.py` | 361 | 56 | **84 %** | Backup dir / edge cases |
44+
| `cli.py` | 572 | 77 | **87 %** | `--gui`, export edge cases |
45+
| `tweaks/__init__.py` | ~800 | ~80 | **~90 %** | ✅ Core engine well-covered |
46+
47+
---
48+
49+
## Tweak Module Coverage (average ~49 %)
50+
51+
The low coverage in tweak modules is **by design**:
52+
53+
- `_apply_*` and `_remove_*` functions call `winreg.SetValueEx` / `winreg.DeleteValue`,
54+
which require a real Windows registry and admin rights.
55+
- These are tested in integration tests on a CI runner with registry access.
56+
- `detect_fn` callability is validated in `test_tweaks_smoke.py`.
57+
58+
| Module | Coverage | Notes |
59+
|---|---|---|
60+
| `tweaks/accessibility.py` | ~51 % | Apply/remove paths uncovered |
61+
| `tweaks/explorer.py` | ~42 % | Largest module (504 stmts) |
62+
| `tweaks/shell.py` | ~35 % | Complex multi-step tweaks |
63+
| `tweaks/win11.py` | ~43 % | Large module (376 stmts) |
64+
| `tweaks/wsl.py` | ~44 % | WSL integration paths |
65+
| *(all others)* | 40–63 % | Pattern consistent across categories |
66+
67+
---
68+
69+
## Coverage Targets
70+
71+
| Target | Current | Goal | Priority |
72+
|---|---|---|---|
73+
| `gui.py` | 13 % | ≥ 80 % | 🔴 P1 (Sprint 4) |
74+
| `gui_widgets.py` | 43 % | ≥ 80 % | 🔴 P1 (Sprint 4) |
75+
| `gui_dialogs.py` | 56 % | ≥ 80 % | 🟡 P2 (Sprint 4) |
76+
| `corpguard.py` | 75 % | ≥ 90 % | 🟡 P2 (Sprint 4) |
77+
| `registry.py` | 84 % | ≥ 95 % | 🟡 P2 (Sprint 4) |
78+
| `gui_tooltip.py` | 74 % | ≥ 90 % | 🟡 P2 (Sprint 4) |
79+
| Overall (non-tweak) | ~81 % | ≥ 95 % | P1 |
80+
81+
---
82+
83+
## Running Coverage Locally
84+
85+
```powershell
86+
# Full report with missing lines
87+
python -m pytest tests/ --cov=regilattice --cov-report=term-missing
88+
89+
# HTML report (open htmlcov/index.html)
90+
python -m pytest tests/ --cov=regilattice --cov-report=html
91+
92+
# Coverage for a specific module only
93+
python -m pytest tests/test_registry.py --cov=regilattice.registry --cov-report=term-missing
94+
```
95+
96+
---
97+
98+
## Improving Coverage
99+
100+
### GUI modules (`gui.py`, `gui_widgets.py`, `gui_dialogs.py`)
101+
102+
Use `unittest.mock.patch` with `tkinter` mocked:
103+
104+
```python
105+
import sys
106+
from unittest.mock import MagicMock, patch
107+
108+
# Mock the entire tkinter module before importing gui
109+
sys.modules["tkinter"] = MagicMock()
110+
sys.modules["tkinter.ttk"] = MagicMock()
111+
sys.modules["tkinter.messagebox"] = MagicMock()
112+
113+
from regilattice import gui
114+
```
115+
116+
### Registry modules (apply/remove/detect)
117+
118+
Use the `dry_session` pytest fixture from `conftest.py`:
119+
120+
```python
121+
def test_apply_tweak(dry_session, monkeypatch):
122+
from regilattice.registry import SESSION
123+
monkeypatch.setattr("regilattice.tweaks.explorer.SESSION", dry_session)
124+
from regilattice.tweaks.explorer import _apply_show_extensions
125+
_apply_show_extensions(require_admin=False)
126+
assert dry_session._write_log # verify a write was recorded
127+
```

0 commit comments

Comments
 (0)