Skip to content

docs(release): v0.3.0 site and changelog, and a guard for egress claims - #141

Merged
ArangoGutierrez merged 5 commits into
mainfrom
docs/v030-release-phase5
Aug 19, 2026
Merged

docs(release): v0.3.0 site and changelog, and a guard for egress claims#141
ArangoGutierrez merged 5 commits into
mainfrom
docs/v030-release-phase5

Conversation

@ArangoGutierrez

Copy link
Copy Markdown
Owner

Problem

v0.3.0 is tagged and its release is published, but the site still advertises 0.2.2. Two of its
pages also carried claims that stopped being true when the update check shipped in this release.

site/index.html said "No network egress ... posts nothing anywhere" and site/privacy.html
said "Nothing. There is no telemetry, no analytics, no crash reporting, and no update ping".
main.swift:164 runs checkForUpdatesIfDue() at launch and UpdateChecker.swift:64 fetches
latest.json from this site, at most once a day and whenever Check now is pressed, with no
setting that turns it off. The privacy page separately said the check "will ship in the next
release" while carrying the stamp "This page describes v0.3.0".

SECURITY.md:76 and docs/ROADMAP.md:88 had already recorded the change. Only the two
user-facing pages lagged, and they are the two a security-minded reader opens first.

Approach

The release move itself: the 0.3.0 entry in CHANGELOG.md and its mirror in
site/changelog.html, six sidebars, three download links, the dl-meta and JSON-LD strings, the
shasum and spctl examples, and the legal stamps. site/latest.json moves with them because
thePublishedManifestStatesTheNewestReleaseTheChangelogRecords holds it against the newest
changelog heading, and because leaving it at 0.2.2 would tell every running copy it is current.
.github/ISSUE_TEMPLATE/release.yml had a stale --keychain-profile coffee-bar;
scripts/release-dmg.sh:33 defaults to coffeebar-app, so the documented command could not work.

The corrections then say what the app does: one outbound request, at most once a day when it
starts and whenever you press Check now, carrying no identifier and downloading no update.

The last commit adds the guard. Both false claims shipped through a green suite because nothing
read egress prose, so noSitePageClaimsTheAppMakesNoNetworkRequest sweeps every page under
site/ and refuses six absolute phrasings. It discriminates on the verb: "needs no network
connection" states a requirement and stays legal, "sends nothing" claims behaviour and does not.
Sections opened by a version heading are exempt, because a released entry describes the build it
shipped with.

Testing done

  • swift test rc=0, Test run with 1235 tests in 12 suites passed, one known issue
    (aScannedFileCarryingARegexLiteralRefusesRatherThanReportingGreen, pre-existing).
  • The guard was mutation-checked twice, once by the implementer and once independently: planting
    The app itself sends nothing. in site/index.html drives rc=1 with a message naming the file
    and the exact phrase, and fails only that page while the other five pass. Restored, tree clean.
  • DMG facts in the changelog were re-measured against build/dist/coffee-bar-0.3.0.dmg rather
    than transcribed: 1054199 bytes, sha256 61009669...3fc441d, arm64, notarised and stapled.

Breaking changes

None. Documentation, site content and one new test.

The 0.3.0 entry lands in CHANGELOG.md and is mirrored into
site/changelog.html, and the six pages now name the release the tag points
at: sidebar, download links, dl-meta, the JSON-LD block, the shasum/spctl
examples and the two legal stamps. The disk-image facts are read off
build/dist/coffee-bar-0.3.0.dmg rather than copied from a draft: 1054199
bytes, sha256 61009669...3fc441d.

Two files outside the drafted census move with them, and both would have
been defects on their own.

site/latest.json is what the update check shipped in this very release
reads. thePublishedManifestStatesTheNewestReleaseTheChangelogRecords holds
it against the newest heading in CHANGELOG.md, so adding the 0.3.0 entry
without bumping the manifest turns that guard red and, worse, tells every
running 0.2.2 copy that it is current on the day 0.3.0 publishes.

.github/ISSUE_TEMPLATE/release.yml phase 2 told the maintainer to run
notarytool with --keychain-profile coffee-bar. scripts/release-dmg.sh:33
defaults KEYCHAIN_PROFILE to coffeebar-app, so the documented command
could never have found the credentials.

The Homebrew claim is left one release behind on purpose, the way #95 did
it: origin/main of ArangoGutierrez/homebrew-coffee-bar still pins
v0.2.2.tar.gz, so honesty constraint 7 and the install page say the two
routes are one release apart rather than claiming a bump nobody has made.

The two 0.3.0 headings use an en-dash where the five older ones use an
em-dash. Both are accepted by the version-heading patterns in
everyReleaseInTheChangelogIsOnTheChangelogPage and
theReleaseFactsOnThePageAreTheOnesInTheChangelog; the em-dash is banned in
new prose by the writing rules this repository is edited under.

Guards: swift test --filter SiteClaims is green, 11 tests, rc 0. The
document sweeps that read the two changelogs are green too, 111 tests
across DocsClaims, PolicyDocumentClaims, UpdateCheck and LidClosedPanel.

No tag was created or moved. Nothing was pushed.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
The front page claimed "No network egress ... posts nothing anywhere" and the
privacy page's summary claimed "Nothing. There is no telemetry, no analytics, no
crash reporting, and no update ping". Both stopped being true when the update
check landed in this release: main.swift:164 runs checkForUpdatesIfDue() at
launch and UpdateChecker.swift:64 fetches latest.json from this site, once a day,
with no setting that turns it off.

The privacy page also still said the check "is now built and will ship in the
next release" while carrying the stamp "This page describes v0.3.0", so it
claimed both that the feature was not here yet and that the page described the
release shipping it.

SECURITY.md:76 and ROADMAP.md:88 already recorded the change. Only the two
user-facing pages lagged, and they are the two a reader checks first.

The detailed disclosure further down the privacy page was already accurate and is
untouched: no query string, no identifier, no cookie, no body, the macOS-added
headers named, and nothing downloaded or replaced.

Found by the release review before the v0.3.0 tag was pushed.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
v0.3.0 ships an update check, so the site's absolute no-egress sentences
became false the moment it went out. 444c330 corrected two of them and
left a third, and traded precision for brevity in the summaries.

The app itself sends nothing: the paragraph's subject is the DMG download
from GitHub, and the intended meaning was that the app plays no part in
that download. Written unqualified it is a present-tense claim that the
app sends nothing at all. Scoped to its subject.

once a day at startup: the check also fires on every launch and on every
Check now press, and Check now ignores the interval entirely
(ServingModel.swift:2167). No timer runs in a long-lived instance, so the
daily figure is a ceiling, not a schedule. Both summaries now say what
UpdateCheck.intervalNote says, which is the phrasing the app itself shows.

downloading nothing: it downloads latest.json. SECURITY.md:83 has the
precise version, that nothing is downloaded but that file, and the claim
worth making is that it downloads no update.

The unix socket clause had drifted onto "everything else", which reads as
though every local thing travels over it. Only agent hook events do, so
the clause goes back to the listener that is its subject.

The changelog called the check the single exception to a promise to make
no network request. SECURITY.md now states it positively, as exactly one
outbound request, and the changelog says the same. No version, date or
heading changes.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Both false egress claims shipped through a green suite, and the second
one survived the pass that fixed the first. That is not bad luck: every
prose guard in DocsClaims_test.swift reads numbers, controls and counts,
and nothing in the repository read an egress sentence at all. The fix
that landed in the previous commit is enforced by nothing without this.

The subject cannot be derived, so it is enumerated. The app does make one
request, so a guard cannot compare a claim against a measurement the way
the duration sweep does. It holds the exact phrasings that are false
while that request exists and refuses to let one back onto a page.

The discrimination is the hard part, and the verb carries it. install.html
says spctl "needs no network connection", which is true and stays legal: a
sentence about what the app NEEDS states a requirement, while one about
what it SENDS, POSTS or REQUESTS claims behaviour. no telemetry, no
analytics, no account and sends no identifier are all still true and all
still pass. theEgressBanFiresOnAbsoluteClaimsAndSparesTheTrueOnes pins
both directions with real sentences, so a pattern narrowed until it
catches nothing fails there rather than going quiet.

Scoped to current claims through currentClaimProse. Before 0.3.0 there was
genuinely no outbound request, so the changelog's 0.2.2 entry was true
when written, and reading history as a live claim would leave falsifying
the changelog as the only route back to green.

Mutation checked: reinserting "The app itself sends nothing." into
site/index.html fails the sweep naming that file and that phrase, and only
that page.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
The 0.3.0 entry said the check "downloads nothing". It downloads
site/latest.json, twenty bytes of JSON naming the current version. SECURITY.md:83
is precise about this ("Nothing is downloaded but that file") and so is the
string the app itself shows ("it downloads no update and installs nothing").

Same imprecision the front page carried and the same correction. The egress guard
cannot catch this one: it exempts sections opened by a version heading, because a
released entry describes the build it shipped with rather than the current app.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
@ArangoGutierrez
ArangoGutierrez marked this pull request as ready for review August 19, 2026 14:17
@ArangoGutierrez
ArangoGutierrez merged commit 8a4e98d into main Aug 19, 2026
2 checks passed
@ArangoGutierrez
ArangoGutierrez deleted the docs/v030-release-phase5 branch August 19, 2026 14:21
ArangoGutierrez added a commit that referenced this pull request Aug 19, 2026
PR #141 banned the absolute no-egress claims on the site and its own report
flagged README, SECURITY and docs as unswept. That left the repository's front
page free to claim exactly what the site was forbidden to claim, which is the
wrong way round: a stranger following a link reads README.md before any page
under site/.

The sweep is now every documented surface minus a named exclusion map, rather
than a list of pages. A list fails open the moment somebody adds a document and
forgets a line, which is the hole discoveredSitePages() was already written to
close for the site half.

Two surfaces are excluded, and neither is a hole in the patterns:

  SECURITY.md quotes both retired false claims while recording when each became
  false. That paragraph is the policy keeping its promise to say so the day an
  outbound request existed, so the ban fires on the prose documenting the ban's
  own subject. Three patterns match there.

  docs/QUICKSTART.md:208 says an unrecognised --tool name "posts nothing rather
  than guessing", which is true of the shim: CoffeeBarShim/main.swift:98-102
  refuses an unknown name with "Nothing was posted." The subject is a local
  unix-socket post and not the app's egress, and the ban reads phrasing rather
  than subjects.

Narrowing "posts nothing" to admit that sentence would blind the ban to "It
posts nothing anywhere.", which is in its own banned fixture list and is one of
the phrasings the false site copy used. The gap is stated instead, in the map,
where the next person to widen the sweep will read it.

theEgressSweepReachesTheReadmeAndExcludesOnlyRealDocuments is the anti-vacuity
half: an argument list that filtered down to nothing would switch the ban off
and report success, and an exclusion naming a document that does not exist would
read like a deliberate gap while excluding nothing.

Mutation proof, planting "coffee-bar makes no network requests at all." in
README.md: the guard fails with README.md carries the absolute claim "makes no
network requests", quoting the surrounding sentence. Restored with git checkout
and green.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Sign up for free to 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