v1.8.0

kevinraymond/fosforav1.8.0Jul 15, 2026by github-actions[bot]

AI Summary

Project rebranding from Phosphor to Fosfora, security updates, and code quality improvements.

Key Highlights

  • Rebranding to Fosfora (Northern Sami for phosphorus)
  • Security advisories and dependency updates
  • Pre-commit hook for code quality
  • Reduced-motion detection for macOS/Windows

New Features

  • Rebranding to Fosfora
  • Security dependency updates (rustls-webpki, tar, anyhow)
  • Pre-commit hook implementation
  • Reduced-motion detection backend
  • CI linting improvements for cross-platform code

Full Release Notes


### Changed
- **Rebranded to Fosfora** — the project, app, window title, NDI source name, macOS bundle, release binaries (`fosfora` / `Fosfora.app`), and documentation are now "Fosfora" (Northern Sami for phosphorus). The signature **Phosphor** effect keeps its name as a heritage nod. Two runtime surfaces are intentionally unchanged this release to avoid breaking existing setups and will migrate later: the config directory (`~/.config/phosphor/`) and the OSC namespace (`/phosphor/*`), along with the Python `bridges/` tooling that targets it. The macOS bundle identifier (`com.kevinraymond.phosphor`) is also unchanged so existing microphone permissions are preserved.

### Fixed (docs)
- **Doc accuracy** — corrected the built-in effect count (23 → 24) and removed the non-existent "Swarm" effect from the README table; corrected the audio-feature count (20 → 46) in the README and tutorials; de-duplicated the AI-assist disclaimer in the README "Note from Dev"; fixed the `.pfx` `passes[].feedback` default in TECHNICAL.md (documented as `false`, actually `true`).

### Security
- **Dependency advisories** — bumped `anyhow` 1.0.102 → 1.0.103 (RUSTSEC-2026-0190, unsound `Error::downcast_mut`) and updated `wayland-scanner`/`uds_windows` patch versions; added documented deny.toml ignores for quick-xml RUSTSEC-2026-0194/0195 (DoS via untrusted XML — only reachable through `wayland-scanner`, a build-time proc-macro parsing trusted bundled protocol XML; remove once the Wayland stack allows quick-xml ≥ 0.41)
- **Dependency advisories** — bumped `rustls-webpki` 0.103.9 → 0.103.13 (RUSTSEC-2026-0049, RUSTSEC-2026-0098) and `tar` 0.4.44 → 0.4.46 (RUSTSEC-2026-0067, RUSTSEC-2026-0068) to clear the cargo-deny audit

### Fixed
- **Multi-pass feedback default** — `passes[].feedback` now defaults to `true`, matching legacy single-shader behavior, so converting an effect from `shader:` to `passes:` no longer silently disables feedback (set `"feedback": false` explicitly to opt out; all built-in effects set it explicitly and are unaffected)
- **Beat pulses no longer dropped** — beats are latched via an atomic counter so 1-frame beat triggers survive channel overflow and multi-frame drains; burst-on-beat effects fire on every beat even under load
- **Visuals settle on audio stall** — held audio features now decay to silence in ~1s instead of freezing at the last loud frame when the device stops delivering data (BPM readout preserved); a watchdog surfaces a status toast once per stall episode (detection only — no auto-reconnect, which could hang on a capture thread blocked in a timeout-less read; on Windows a >10s playback pause may trigger the toast since WASAPI loopback delivers no packets during silence)
- **Normalizer field pass-through** — all beat-detector-owned features (onset, beat, beat_phase, bpm, beat_strength) now bypass adaptive normalization; an off-by-one index range previously misclassified onset and beat
- **Recording A/V sync** — audio recording now starts from the moment recording begins instead of draining minutes of stale ring-buffer history into the encoder; ring-buffer reads are also clamped to capacity so a lapped consumer recovers with the newest window
- **Save errors surfaced** — effect saves (particle definition and debounced parameter saves) and recording-start failures now show a status-bar error toast instead of failing silently; a failed parameter save no longer marks the shader editor's paired `.pfx` as clean
- **Clippy warnings** — cleared 13 default-feature clippy lints (collapsible match guards in `app.rs`/`main.rs`/`web/state.rs`, derivable `Default` for `ParticleQuality`, redundant `String` clones in UI panels)
- **Depth feature** — `depth` feature now depends on `webcam` (depth estimation requires webcam input), eliminating dead-code warnings when building with `--features depth` alone
- **Windows CI warnings** — removed unused import, allowed dead code on `wasapi_available()`, fixed unreachable expression in `create_audio_fifo()`, fixed function pointer cast in midir patch
- **Cross-target clippy debt** — fixed a Windows-only `ptr_as_ptr`/`ptr_cast_constness` violation in `wasapi_capture.rs` and a `webcam`/`depth`-feature `implicit_clone` in `webcam.rs`, both previously invisible to the host-only clippy runs (board #1500)

### Added
- **Pre-commit hook** — `.githooks/pre-commit` runs `cargo fmt --check` and `cargo clippy -D warnings`
- **Reduced-motion detection (macOS/Windows)** — implemented the platform detection that was previously stubbed to always return `false`: macOS via `NSWorkspace.accessibilityDisplayShouldReduceMotion` (objc2-app-kit), Windows via `SystemParametersInfoW(SPI_GETCLIENTAREAANIMATION)`. Linux (gsettings) already worked. This is the detection backend only — `ReducedMotion` is not yet consumed by any effect/animation, so there is no user-visible behavior change until it is wired in

### Changed
- **CI lints cfg-gated platform code** — the cross-OS `build` matrix now runs `cargo clippy -D warnings` per native target (Linux/macOS/Windows), so `#[cfg(target_os = …)]` code that host-only clippy never compiled is finally linted; the Linux `lint` job now denies warnings too (matching the pre-commit hook). The pre-commit hook stays host-only for fast commits — see CONTRIBUTING.md for the manual cross-target command. (board #1500)
- **README** — expanded build-from-source section with per-feature prerequisites; added Binding Matrix section and `B` keyboard shortcut
- **NDI docs** — clarified that NDI output is built into official release downloads (only the NDI runtime needs installing); the `--features ndi` flag now framed as a from-source-only step in README and TUTORIALS

### Documentation
- **Stale-docs sweep** — corrected the `AudioFeatures` doc comment (45 → 46 features) and renamed the byte-size test to match its 184-byte assertion; fixed the audio-panel footer to report the real multi-resolution FFT sizes (`4096/1024/512` rather than a bare `512`)

## Downloads

| Platform | File | Notes |
|----------|------|-------|
| **macOS** | `.dmg` | Universal binary (Apple Silicon + Intel) |
| **Linux x86_64** | `.tar.gz` | glibc 2.35+ (Ubuntu 22.04+, Debian 12+) |
| **Windows x64** | `.zip` | Windows 10+ |

## Getting started

**macOS**: Open the DMG, drag Fosfora.app to Applications (or run directly). Signed and notarized.

**Linux / Windows**: Extract, run `fosfora` from the extracted directory. The `assets/` folder must be next to the binary.

## Requirements

- **GPU**: Vulkan (Linux/Windows) or Metal (macOS)
- **Audio**: Built-in mic or line-in for audio-reactive visuals
- **NDI®** (optional): [NDI® SDK runtime](https://ndi.video) for network video output
- **Video playback** (optional): `ffmpeg` on PATH for media layers

---
NDI® is a registered trademark of Vizrt NDI AB.