# Changelog

All meaningful changes to this repository should be recorded here.

## Unreleased — 2026-05-22 (Audit round 3)

### Security
- **Fail-closed leak detection**: `is_chain_leak()` now treats unknown direct
  IP as a leak (was: pass-through).  `service.py` retries direct-IP lookup
  3× with 2 s back-off as a warm-up grace so transient network blips don't
  cause permanent rotation.

### Reliability
- **Single asyncio loop in preflight**: removed per-call `asyncio.run()` from
  the preflight worker thread; one loop is created, drained, and closed.
- **Close-window UX**: X button now prompts when chain or firewall is still
  active (tray / full quit / cancel) instead of silently minimizing.
- **Admin relaunch**: settings persist before the elevated process spawns.
- **Persona/cookie key lookup**: precomputed `label→key` dicts; label copy
  changes can no longer break the round-trip.

### Distribution
- **GOST bundled**: `scripts/prepare_bundled_gost.ps1` downloads and SHA-
  verifies `gost.exe`, stages it under `proxy_chain_manager/_bundled/`, and
  PyInstaller bundles it into the exe.  `ensure_gost()` installs from the
  bundle on first run (no internet required); network fetch is fallback only.

### Tests
- New suites: `test_config_round_trip`, `test_ban_tester`, `test_gost_util`,
  `test_fail_closed`, `test_firewall_helpers`.
- Total: **47 → 82** passing.

### Held by design (audit §12)
- Signup extension stays on `<all_urls>` — custom signup URLs need it.
- `verify=False` on httpx probes — broken public-proxy TLS.
- DNS pass-through in kill-switch — GOST needs system DNS.
- Authenticode signing — pending Cert provisioning.

## Unreleased — 2026-05-21 (Audit remediation P0/P1/P2)

### Security (P0)
- **Secrets at rest**: Added `_mask()` helper in `config.py` to redact credentials from any
  debug log output.  Added `SETTINGS_SCHEMA_VERSION` and prominent plaintext-storage warning.
- **GOST integrity**: `gost_util.py` now verifies the downloaded release zip against a pinned
  SHA256 (`GOST_RELEASE_ZIP_SHA256`) before extraction.  Supply-chain swap raises `RuntimeError`.
- **Kill-switch recovery**: `firewall.py` exposes `emergency_disengage()`.  `service.py`
  registers it via `atexit` and `signal.SIGTERM`/`SIGINT` so a crash cannot leave outbound
  traffic permanently blocked.

### Reliability (P0/P1)
- **Top-level exception handler**: `app.py` `main()` now catches unhandled exceptions, shows a
  `tkinter.messagebox` error dialog, logs to file, and re-raises.
- **Log rotation**: `app.py` switches from bare `FileHandler` to `RotatingFileHandler`
  (5 MB max, 3 backups).
- **Settings migration**: `config.py` gains `settings_version` field, `migrate()` function, and
  safe corrupt-file backup (`settings.json.corrupt`) on parse failure.
- **Settings backup**: `save_settings()` copies `settings.json → settings.json.bak` before
  overwriting.
- **Graceful shutdown**: `service.py` `stop()` calls `fw_emergency_disengage()` if the thread
  does not exit within 15 s.
- **Thread safety**: `ChainService._settings` reads/writes guarded by `threading.Lock`.
- **Input / URL validation**: `sanitize_settings()` now validates `sources` and `ip_check_url`
  against an RFC-1918 / link-local block-list; unsafe entries are removed with a warning.

### CI / Distribution (P0/P1/P2)
- **GitHub Actions CI** added: `.github/workflows/test.yml` runs `compileall` + `unittest
  discover` on Python 3.10 / 3.11 / 3.12 on `windows-latest`.
- **LICENSE**: MIT license added to repo root.
- **requirements.txt**: All four runtime dependencies pinned to exact versions; `cryptography`
  listed for optional future credential encryption (not yet wired).
- **`.gitignore`**: Added `settings.json`, `*.json` credential files, and screenshot noise.
- **`--version` flag**: `run.py` now supports `--version` / `-V`.

### Documentation (P1/P2)
- **`docs/OPERATOR_RUNBOOK.md`**: Emergency firewall disengage, proxy leak, empty pool, GOST
  quarantine, and settings-restore instructions.
- **Bare `except: pass` cleanup**: Key silent-failure sites in `tray.py`, `dns_leak.py`, and
  `gost_util.py` now log a `warning` or `debug` message instead of swallowing errors.

## 2026-05-20 - Gitea Stewardship Import

- Verified README and wiki coverage.
- Added standard stewardship documentation where missing.
- Established security, contribution, release, and provenance expectations.
