Tell the user a newer build exists, after asking whether to look - #70
Merged
Conversation
There is no auto-update and there will not be. The Windows build is unsigned, and a program that downloads and runs code on its own is precisely the behaviour this project tells teachers to be suspicious of. But without one, somebody who downloaded 0.2.0 in July is still running it — and 0.2.0 gives a verdict on a pasted paragraph, which we now know is a verdict about a length nobody measured. Leaving them there is its own harm. So the app can look, and report a number and a link. The person decides. It asks first. That is the part worth arguing about and the part I would not give up: this is the first network call the app would make without being asked, and a tool whose case rests on "nothing leaves your machine" does not get to make an exception quietly — not even one that sends no text, no account and no identifier. A quiet strip on first run, two buttons, remembered, changeable on the Windows app page. Until it is answered, nothing is checked. What actually leaves: one GET to the public releases endpoint. GitHub sees an address and a user agent, the same as if the person opened the releases page in a browser. At most once a day — sixty unauthenticated requests an hour are shared by every machine behind a school's NAT, and a class exhausting the limit between first and second period would be our fault. Failure is silence. Offline, a proxy returning an HTML login page, a rate limit, a malformed body: all return the same nothing as "you are up to date", because an error banner about a version check, on a page about somebody's essay, is noise the reader cannot act on. The half that can be quietly wrong is the version picking, so it is pure, lives next to the tag convention it depends on, and is tested without a network. Ordering by date would pick a NuGet release with no app attached, since the two tag lines interleave. Ordering as text would put 0.10.0 before 0.4.0 and tell everyone they were up to date for the rest of the project's life — the kind of bug nobody reports, because the message simply never appears. The README's privacy paragraph says all of this, and says explicitly that this is not a fifth exception to the four: those four can send your text, and this one cannot send anything. 417 tests, 17 new. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015PEbbiYSNPw7jE3LrPNhyF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The desktop app has no auto-update and never will — the build is unsigned, and a program that
downloads and runs code on its own is precisely the behaviour this project tells teachers to be
suspicious of.
Without one, though, somebody who downloaded 0.2.0 in July is still running it. And 0.2.0 gives a
verdict on a pasted paragraph, which since #59 we know is a verdict about a length nobody measured.
Leaving them there is its own harm.
So the app can look, and report a number and a link. The person decides.
It asks first
This is the first network call the app would make without being asked, and a tool whose case rests on
"nothing leaves your machine" does not get to make an exception quietly — not even one that sends no
text, no account and no identifier.
A quiet strip on first run:
Until it is answered, nothing is checked. The answer is remembered and can be changed on
/download, which is already the page about versions in the desktop host.When there is something to say:
Told once per version, not once per launch.
What actually leaves the machine
One GET to the public releases endpoint. GitHub sees an address and a user agent — the same as if the
person opened the releases page in a browser.
At most once a day. Sixty unauthenticated requests an hour are shared by every machine behind a
school's NAT, and a class exhausting the limit between first and second period would be our doing.
Failure is silence. Offline, a proxy returning an HTML login page, a 403 rate limit, a malformed
body — all return the same nothing as "you are up to date". An error banner about a version check, on
a page about somebody's essay, is noise the reader cannot act on.
It never downloads or runs anything. The link goes to the release notes; a test asserts the URL
contains neither
.zipnor/download/.The half that can be quietly wrong
Version picking is pure, lives next to the tag convention it depends on (
DesktopRelease), and istested without a network — because two plausible implementations are wrong in ways nobody would
report:
live API right now returns
desktop-v0.4.0, v0.4.0, desktop-v0.3.0, v0.3.0, ….0.10.0before0.4.0and tells everyone they are up to date for therest of the project's life. The message simply never appears, so nobody files a bug.
Prereleases and unparseable tags are ignored rather than guessed at.
Shape
IUpdateCheckfollowsIFolderBatch: a capability in the shared UI with a no-op browserimplementation (
NoUpdateCheck— a tab is always whatever was last deployed, so it renders nothing atall) and a real one in the desktop host.
UpdatePreferenceowns consent, the daily schedule and thedismissed version, so there is one answer to "may we check?" rather than one per surface.
Documented, not buried
The README's privacy paragraph now carries it, and says explicitly that this is not a fifth
exception to the four: those four can send your text; this one cannot send anything.
Verified
before committing — no test scaffolding ships.
0.4.0correctly.🤖 Generated with Claude Code
https://claude.ai/code/session_015PEbbiYSNPw7jE3LrPNhyF