# Changelog — RevivoPlus for macOS

All notable changes to this project are documented here.
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
Versioning: MAJOR.MINOR.PATCH (build YYYYMMDD).

## [1.0.0] (build 20260503) — 2026-05-03

First release of the native macOS port (Swift + SwiftUI + AppKit). Replaces
the Avalonia/.NET version (`../RevivoPlus_Mac/`), deprecated due to an
NSStatusItem registration bug in Avalonia 11.2.7 on macOS 26.5/arm64.

### Security (initial security review + remediation, see SECURITY_REVIEW.md)
- **HIGH H1** — SMTP / Telegram bot token credentials migrated from the
  settings JSON to the Keychain via the new `SecretsStore`. Automatic
  migration from legacy settings.json. Exported profiles now secret-free
  by construction.
- **HIGH H2** — MIME header sanitization (CRLF strip on Subject / From /
  To / Date / X-Mailer) and SMTP body dot-stuffing (RFC 5321 §4.5.2) to
  close header injection and SMTP smuggling.
- **MEDIUM M1** — `killall` used as fallback in ScheduleChecker now
  scoped to the current user (`-u $USER`) with a blocklist for system
  process names.
- **MEDIUM M2** — crimson UI banner when SMTP is plaintext and
  credentials are present, to avoid unintentional submit.
- **MEDIUM M3** — single-instance check rewritten with atomic `flock(2)`
  on a 0600 lock file, replacing the previous `runningApplications`
  check (TOCTOU).
- **MEDIUM M4** — 1 MB cap on settings.json and imported profile size
  before deserialization.
- **LOW L1** — removed unused `NSAppleEventsUsageDescription` from
  Info.plist (least privilege).
- **LOW L2** — `importProfile` rejects symlinks, validates JSON before
  writing, applies 0o600/0o700 permissions.
- **LOW L3** — replaced stderr with `AppLog` on a private file
  `Logs/app.log` (0o600); LSUIElement → stderr would land in the
  public system log.

### Technical notes
- Every source file starts with `// (c) 2026 Iuri Vaccari — labforge.tech`

### Added
- Tray-only app (LSUIElement) with native NSStatusItem and full menu
- Monitoring of up to 10 simultaneous apps with auto-restart, duplicate
  dedup, automatic cooldown after 5 consecutive failed restarts (2 minutes)
- Per-app scheduling: daily, weekly, monthly (start-stop window, with
  process kill at pause start)
- Live SwiftUI dashboard (Table) with status, uptime, restarts, duplicates,
  last crash, check interval
- Multi-channel notifications: macOS toast (UserNotifications), Email
  (SMTP via Network.framework with STARTTLS / implicit TLS / AUTH LOGIN),
  Webhook (HTTP POST JSON), Telegram (Bot API)
- Severity policy with "N crashes in M minutes" threshold that escalates
  from Warning to Critical
- JSONL logging in `~/Library/Application Support/RevivoPlus/Logs/`
  with configurable purge (1–365 days)
- Named profiles with JSON import/export in
  `~/Library/Application Support/RevivoPlus/Profiles/`
- Daily/Weekly reports with totals, per-app breakdown and CSV export
- Full IT/EN localization of every UI string
- EULA on first launch with privacy summary, system disclaimer and
  jurisdiction statement
- About panel with the labforge crimson mark/wordmark (PNG rendered from
  the master SVG via qlmanage), app identity, copyright, site link,
  system disclaimer
- Canonical PayPal donation section: presets 1/2/5/10 EUR + custom,
  IT/EN copy, CTA opening the system browser, legal notes
- Offline help system with sections Getting Started / Features /
  Shortcuts / FAQ / Release Notes
- labforge.tech canonical palette applied via `Theme/BrandPalette.swift`
  (Crimson #c03040, Steel #7890a0, Bone Ivory #b89860, Sage #6a9070;
  backgrounds and text WCAG AA)
- Build script `Scripts/build-mac.sh` that assembles the `.app` bundle
  with Info.plist, AppIcon.icns from the labforge drop-in package,
  separate dSYM in release, strip, automatic code signing (Developer ID
  if available, otherwise ad-hoc), optional DMG

### Technical notes
- Every source file starts with `// (c) 2026 Iuri Vaccari — labforge.tech`
- Settings/profile JSON uses PascalCase CodingKeys for 1:1 parity with
  the Windows version (profile exchange compatible)
- Single-instance check via atomic `flock(2)` on `.instance.lock` 0600
- Min macOS 13.0; SwiftPM executable target, no Xcode project
