Skip to content

Make the licences readable from inside the app - #37

Merged
revtex merged 1 commit into
mainfrom
feat/third-party-notices
Aug 15, 2026
Merged

Make the licences readable from inside the app#37
revtex merged 1 commit into
mainfrom
feat/third-party-notices

Conversation

@revtex

Copy link
Copy Markdown
Owner

Phase 8's remaining item: third-party notices reachable from inside the app, not only as a file in the repo. It turned up a second gap on the way — nothing in the app carried the Spotify attribution its Developer Terms require.

What changed

A notices window. "Licence and notices" on the Advanced page's Application section opens Offstream's MIT licence, the predecessor's copyright notice, the bundled LGPL-3.0-or-later ffmpeg and its source offer, TagLib# (LGPL-2.1-only) and VB-CABLE's origin and donationware terms. The running version and short commit sit at the top, so a bug report can name its build.

The text is embedded, not read from disk.LICENSE and NOTICE are EmbeddedResource items in Offstream.App.csproj. Both licences oblige the notice to travel with the software, and a loose file does not survive a zip unpacked selectively, a copy of just the .exe, or a run out of bin\. ThirdPartyNoticesTests asserts the shown text still contains what both files say, so the window and the repository cannot drift.

Attribution beside the provider. CLAUDE.md says attribution lives on the Settings page next to the provider that requires it. It did not — Strings.resx had 131 keys and none of them credited anyone. Selecting Spotify or Last.fm now says whose data is being written into the recordings. It is empty for "Nothing": crediting a service the app is not calling is a false statement.

The placement is load-bearing

The first attempt put a version line and a button under the ffmpeg path. Both were clipped off the bottom of the window at its minimum size — the shell's MinHeight is a written promise that no setting is ever unreachable without scrolling, and this broke it silently. Raising the floor was not available either: at 150% scaling the window is already 1050 physical pixels tall, so a taller minimum stops fitting a 1080p screen.

The section header line is the one place in a full card with room that costs nothing vertically; the rule simply runs up to the link instead of across. Anything added to the Advanced page from here needs the same arithmetic done first, and the finding says so.

Verified

  • 1105 tests green, dotnet format --verify-no-changes clean, analyzers as errors.
  • Ran the app and captured both surfaces: the notices window renders with 0.1.0-dev+90360c5 at the top, and the attribution line renders under the provider summary. The Advanced page's Application card is unchanged in height.
  • The attribution capture was cropped to the provider column by element bounds, so no credential field was ever in frame.

Also here

  • Phase 8 findings in docs/MODERNIZATION-PLAN.md, and a status line stating plainly that the clean-VM install → record → uninstall pass has not happened. It needs a virtual machine and a person at it; CI installs and uninstalls nothing, so it is not a substitute. The installer is known to compile and known to produce an executable, which is a weaker claim than the exit criterion makes.
  • The update bullet corrected. Question 4 was answered "skip for v1", but the plan had gone on to describe an in-app check that asks GitHub for the newest tag and links to it — a network call, a settings toggle and a pair of localised strings, which is a feature rather than the absence of one. Six places said it; all six now say there is no update mechanism, and the exit criterion's update leg is replaced by the installer's own upgrade path rather than reinterpreted.

Notes

  • New keys are in both Strings.resx and Strings.fr.resx — the parity test fails the build otherwise.
  • Services/ThirdPartyNotices.cs imports System.IO explicitly. The throwaway project WPF builds first to resolve XAML type references does not inherit ImplicitUsings, and the error names a _wpftmp.csproj that does not exist on disk.

Two obligations were being met on paper and not in practice.
NOTICE and LICENSE shipped as files beside the executable. That satisfies the
predecessor's MIT notice and the bundled LGPL ffmpeg only for as long as the
files stay next to the .exe, which a zip unpacked selectively or a copy of just
the executable does not guarantee - and nobody opens a folder to read one
anyway. Both files are embedded in the assembly now and shown by a window the
Advanced page links to, with the running version and short commit at the top so
a bug report can name its build. A test asserts the window still contains what
the two files say, so they cannot drift apart.
The second was missing outright: nothing in the app credited Spotify or Last.fm
for the track details it writes into recordings, though Spotify's Developer
Terms require it. The line sits under the provider picker, where it is obvious
what it refers to, and is empty for "Nothing" - an attribution to a service the
app is not calling is a false one.
The entry point is on the Application section's header rather than under the
last setting, and that is not cosmetic. A version line and a button below the
ffmpeg path pushed both off the bottom edge at the window's minimum size, which
is the shell's written promise that no setting is unreachable without
scrolling. Raising the floor is not available - at 150% scaling the window is
already 1050 physical pixels tall - so the header line is the only room in a
full card that costs nothing.
Also records the Phase 8 findings and states plainly what is still not done:
the clean-VM install to uninstall pass needs a virtual machine and a person at
it, and CI does not substitute for it.
@revtex
revtex merged commit 45b86b5 into mainAug 15, 2026
6 checks passed
@revtex
revtex deleted the feat/third-party-notices branch August 15, 2026 03:55
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@revtex