Files
freno-dev/marketing/drafts/privacy-page.patch
fixture fd91b0d3ef privacy: name the IP address and describe the TestFlight build as it ships (FRE-1480)
CTO verdict at FRE-1480: two sentences at db3e695 were false.

(b) sendDefaultPii = false does not stop Sentry receiving the connection
IP (sentry-cocoa 9.26.1 sets infer_ip = auto for Cocoa; only the Sentry
project's Prevent Storing of IP Addresses switch stops it) — the shipped
Settings rows already say so. The IP sentence is restored.

The iPhone paragraph described an opt-in build no tester has: the build
in TestFlight (ios-v0.3.2, 2026-10-22) predates FRE-355 and starts
Sentry on every launch with no off switch. The paragraph now says that.

Header comment and marketing/drafts/privacy-page.md rows corrected to
match (release range narrowed to 0.3.0-0.15.0; evidence rows record the
IP and the TestFlight provenance). privacy-page.patch regenerated.

Suite: merge tree of a0e6ff1 + this branch runs the same failure set as
clean a0e6ff1 (2 junit failures, the known Lineage-redirect
environmental pair); the host's env-validation aborts account for the
count noise. Zero new failures.
2026-11-06 13:26:24 +00:00

238 lines
14 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
diff --git a/src/routes/nook/privacy.tsx b/src/routes/nook/privacy.tsx
index da0cc1d..db27d8c 100644
--- a/src/routes/nook/privacy.tsx
+++ b/src/routes/nook/privacy.tsx
@@ -1,9 +1,38 @@
/**
* The Nook privacy policy — `nook.freno.me/privacy`.
*
- * Reflects the actual data The Nook sends when licensing: a masked hardware
- * UUID + device name for trial/activation limits, the email used for purchase,
- * and Stripe payment processing.
+ * Every statement on this page is traced to the egress inventory at
+ * `The-Nook` HEAD (FRE-333, `document-egress-inventory`): eleven internet
+ * destinations, file:line evidence per row. When the app's egress changes,
+ * this page changes in the same commit — not later.
+ *
+ * The crash-reporting paragraphs ((b) and the iPhone companion) describe the
+ * build users run today: crash reporting is opt-in, off by default, on
+ * releases v0.15.1 and later — FRE-355 (merge `6e74b261`) first shipped in
+ * `v0.15.1` (2026-11-04), and the live appcast serves `v0.15.2`. When enabled,
+ * Sentry receives crash and error reports, session pings, and performance
+ * traces at a 0.1 sample rate (`tracesSampleRate = 0.1`), and it also receives
+ * the connection's IP address (`sendDefaultPii = false` is the SDK default and
+ * does not suppress it — sentry-cocoa 9.26.1 sets `infer_ip = auto` for Cocoa,
+ * and only the Sentry project's *Prevent Storing of IP Addresses* switch stops
+ * that; FRE-1480). Releases 0.3.0 through 0.15.0 started Sentry on every
+ * launch with `sendDefaultPii = true` and no off switch; this page describes
+ * the current release. The iPhone paragraph describes `ios-v0.3.2`
+ * (2026-10-22, the build in TestFlight) until an `ios-v*` tag carries
+ * FRE-355's opt-in code.
+ *
+ * The *Contingency* in `marketing/drafts/privacy-page.md` fired with `v0.15.1`
+ * and is applied in this commit, with two corrections against the pre-written
+ * swap text: the shipped build still sends session pings and traces while
+ * enabled, so they are named (the contingency's own completeness warning), and
+ * the IP sentence is kept — the pre-written swap text already had it, and
+ * `sendDefaultPii = false` does not stop Sentry receiving the IP (FRE-1480).
+ *
+ * Corrected against the CTO's /privacy verdict (FRE-354): no macOS username
+ * from Sentry (sendDefaultPii sets the IP only), session pings named, (a)
+ * fail-open scoped, (c) relay-path qualified with the direct-pair sentence,
+ * (j) "not a cloud service" with the tailnet path, the iPhone paragraph added
+ * (TestFlight beta is in users' hands), and section 3 says "content".
*/
import { buildMainSiteUrl } from "~/lib/subdomain-url";
import { PageHead } from "~/components/PageHead";
@@ -21,39 +50,139 @@ export default function NookPrivacyPolicy() {
<SubdomainHeader />
<div class="min-h-screen px-[8vw] py-[10vh]">
<div class="py-4 text-xl">The Nook&apos;s Privacy Policy</div>
- <div class="py-2">Last Updated: August 26, 2026</div>
+ <div class="py-2">Last Updated: November 6, 2026</div>
<div class="py-2">
- Welcome to The Nook (&apos;We&apos;, &apos;Us&apos;, &apos;Our&apos;).
- Your privacy is important to us. This policy explains what we collect,
- why, and how it is handled. The app itself runs locally on your device
- and sends only the minimal data required for trial and licensing.
+ The Nook runs on your Mac, and the iPhone and Apple Watch companion
+ is in TestFlight beta. Your prompts, your code and your agent
+ sessions are processed on your own devices. This page lists every
+ connection the apps make over the internet — and the local-network
+ and tailnet paths the phone can use — what each one sends, and
+ whether you can turn it off.
</div>
<ol>
<div class="py-2">
<div class="pb-2 text-lg">
- <span class="-ml-4 pr-2">1.</span> Data We Collect
+ <span class="-ml-4 pr-2">1.</span> What leaves your devices
</div>
<div class="pl-4">
<div class="pb-2">
- <div class="-ml-6">(a) Device hardware UUID:</div> When you start
- a trial or activate a license, The Nook sends a hardware UUID
- from your Mac. It is used solely to enforce the 14-day trial and
- the 3-device activation limit, and to prevent resetting the
- trial by reinstalling the app.
+ <div class="-ml-6">(a) Licensing and trial:</div> When you start
+ a trial or activate a license, The Nook sends your Mac&apos;s
+ hardware UUID and device name to our licensing server
+ (freno.me). The UUID enforces the 14-day trial and the 3-device
+ activation limit and stops a trial being reset by reinstalling
+ the app; the device name is stored with the activation so the
+ Mac can be identified in your license records. While you are on
+ the trial, this is sent at each launch. Once you are licensed,
+ each launch re-checks only that your key has not been revoked.
+ Deactivating a Mac sends the license key and that Mac&apos;s
+ UUID. If you add an email during the trial, that request
+ carries the email and the UUID, and it is sent once. The trial
+ and status checks fail open: with no connection, an unexpired
+ trial or a stored license keeps working, because license
+ verification itself is offline. Activating a new license needs
+ a connection once.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(b) Crash and error reporting — off unless
+ you turn it on:</div> Crash reporting is off by default and
+ runs only if you enable it in Settings. When it is on, The Nook
+ sends crash reports, error events, hang reports, session pings,
+ and a sample of performance traces to Sentry, our
+ crash-reporting processor. Each report carries the app version,
+ the macOS version, the Mac model and what the app was doing
+ when it failed. Sentry also receives your IP address. They
+ never include your prompts, your code or your session content.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(c) Phone connection:</div> The phone
+ connection ships off and is yours to enable. With the default
+ relay path, turning it on registers your Mac with our relay
+ (nook-relay.freno.me) using a random install ID, and a licensed
+ Mac presents its license key once at registration. Everything
+ your Mac and your phone then exchange — session updates,
+ approvals, replies — is encrypted end-to-end: the relay routes
+ it and cannot read it. On the relay path, the relay can see
+ which devices are connected — their IDs, names and platforms —
+ when, and how much traffic they exchange.
+ </div>
+ <div class="pb-2">
+ You can also pair over your LAN or tailnet instead; those paths
+ carry the same sealed traffic and do not use the relay.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(d) Weather:</div> If you add the Weather
+ module, your Mac asks our relay for forecasts using coordinates
+ rounded to a 0.1° grid — about 11 km — and the rounding happens
+ on your Mac before anything is sent. The Weather module
+ registers with the relay for this even if you never turn on the
+ phone connection, and on a licensed Mac that registration
+ presents the license key, exactly as the phone connection&apos;s
+ does. &quot;My Location&quot; asks macOS for your
+ approximate position, and naming or searching for a place uses
+ Apple&apos;s Maps service, so Apple sees those lookups. Neither
+ feature sends us your precise location.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(e) The Network panel:</div> While the
+ Network panel&apos;s connection section is on screen, The Nook
+ asks a third-party IP-lookup service (get.geojs.io, with
+ ipwho.is as backup) what your public IP address and provider
+ are — that is how the panel can show them to you. Those services
+ necessarily see your IP address. The speed-test button measures
+ against Cloudflare&apos;s public speed endpoint and uploads only
+ zeros, never your data.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(f) Update checks:</div> Automatic update
+ checks ship off. If you turn them on, or press &quot;Check for
+ Updates&quot;, The Nook fetches the update feed from freno.me
+ and the request carries your app version. Like every request on
+ this page, it also arrives from your IP address.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(g) Changelog:</div> Opening Settings ›
+ Changelog fetches the release notes from freno.me.
+ </div>
+ <div class="pb-2">
+ <div class="-ml-6">(h) Bug reports:</div> only what you choose
+ to send. If you write a bug report, you decide what it says.
+ Bug reports also include a machine snapshot — macOS version, Mac
+ model, CPU, memory, free disk, locale, and your displays&apos;
+ names and resolutions — so the problem can be reproduced. The
+ optional contact email is used only to reply to you.
</div>
<div class="pb-2">
- <div class="-ml-6">(b) Device name:</div> The Nook sends your
- Mac&apos;s name so you can recognize the device in your license
- activations. It is not used for any other purpose.
+ <div class="-ml-6">(i) Your email and payment:</div> The email
+ you give at checkout delivers your license key and looks up your
+ order. An email you add during the trial is used for one
+ reminder before the trial ends. Payments are processed by
+ Stripe; we never see or store your card details.
</div>
<div class="pb-2">
- <div class="-ml-6">(c) Email:</div> The email you provide at
- checkout is used to deliver your license key and to look up your
- order.
+ <div class="-ml-6">(j) What does not leave your Mac:</div> The
+ hook and the bridge that connect your agents to The Nook are
+ not a cloud service: the hook dials the bridge on your Mac, and
+ the bridge only listens. Two paths carry agent data across the
+ network, and both are switched on by you: if you add a remote
+ machine, the hook on that machine dials this Mac over SSH or
+ your tailnet; and if you use the phone connection, the session
+ updates, approvals and replies described in (c) travel through
+ the relay, sealed end to end. The privileged helper that
+ controls fans and charging has no networking code at all.
</div>
<div class="pb-2">
- <div class="-ml-6">(d) Payment:</div> Payments are processed by
- Stripe. We never see or store your card details.
+ <div class="-ml-6">The iPhone companion.</div> The iPhone and
+ Apple Watch app is in TestFlight beta. The build in TestFlight
+ starts Sentry on every launch, with no setting that turns it
+ off: it sends crash, error and hang reports, session pings,
+ performance traces, the app version, the iOS version, the
+ iPhone model and your IP address. Those reports never include
+ your prompts, code or session content.
+ Its other network traffic is the phone connection in (c) — the
+ relay, or a direct LAN/tailnet link — plus, if you allow
+ notifications, the push token it gives the relay so Apple can
+ deliver them.
</div>
</div>
</div>
@@ -63,9 +192,11 @@ export default function NookPrivacyPolicy() {
<span class="-ml-4 pr-2">2.</span> How We Use It
</div>
<div class="pb-2 pl-4">
- Device identifiers, your email, and license records are used only
- to operate the trial, deliver purchases, and enforce the 3-device
- license. We do not use them for advertising or sell them to anyone.
+ Device identifiers, install IDs, your email and license records are
+ used only to operate the trial and the licenses, to run the relay
+ and the weather service, to answer bug reports, and to deliver
+ purchases. We do not use them for advertising and we do not sell
+ them to anyone.
</div>
</div>
@@ -74,9 +205,13 @@ export default function NookPrivacyPolicy() {
<span class="-ml-4 pr-2">3.</span> Data Security
</div>
<div class="pb-2 pl-4">
- License keys are signed and verified with Ed25519. The connection
- to our servers uses TLS. Your license key is stored in the macOS
- Keychain on your Mac.
+ License keys are signed and verified with Ed25519 and stored in
+ the macOS Keychain. The session content your Mac and phone
+ exchange is encrypted end-to-end with keys your devices generate
+ at pairing; our relay holds no key that can read it, though it
+ can read the routing metadata described in (c). Every internet
+ connection described on this page uses TLS; the direct
+ LAN/tailnet paths use the same end-to-end encryption.
</div>
</div>