forked from Mike/freno-dev
privacy: apply the FRE-354 verdict corrections to the /privacy replacement
FRE-354 ruled the page 'verified after corrections — do not apply as it
stands'. This applies all of them, plus the two copy decisions the verdict
delegated to the CMO (fuller iPhone paragraph; full (c) block with the
LAN/tailnet sentence and the matching section-3 clause).
- (b) no macOS username (sendDefaultPii sets the IP only), session pings
named; still the always-on form: no release tag contains FRE-355's
opt-in merge (6e74b261; v0.15.0 predates it), so the page stays true on
the build users run. Contingency swap owed with the first release that
ships FRE-355.
- (a) device-name sentence corrected (no activations UI exists); fail-open
scoped to trial/status, activation needs a connection once.
- (c) relay qualified as the default path; relay sees IDs/names/platforms;
direct LAN/tailnet pairing sentence added.
- (j) 'not a cloud service' instead of two absolutes FRE-322 flagged;
tailnet path named.
- iPhone companion paragraph added (TestFlight beta is in users' hands,
same Sentry config, push token disclosed). Push-token evidence row
recorded for FRE-333's inventory.
- Opening, section heading ('What leaves your devices') and section 3
('content', not all traffic) per the verdict; Last Updated bumped.
- Draft evidence table and contingency warning rewritten per the verdict
(the old warning named a username Sentry never sends).
Suite on this tree: 441 pass / 3 skip / 53 fail / 2 errors — failure and
error sets byte-identical to clean master d44133f (458/3/53/2; the delta
is master's remote-claims.test.ts, 17 passing tests this branch's base
predates). Local only; the push is the sponsor's (card 392a8465).
This commit is contained in:
@@ -6,12 +6,20 @@
|
||||
* destinations, file:line evidence per row. When the app's egress changes,
|
||||
* this page changes in the same commit — not later.
|
||||
*
|
||||
* The crash-reporting paragraph below describes the build that ships today:
|
||||
* The crash-reporting paragraph below describes the build users run today:
|
||||
* Sentry starts unconditionally in `Sources/NookApp/main.swift:272-279`, with
|
||||
* `sendDefaultPii = true`, and there is no off switch in Settings. If an
|
||||
* opt-in setting ships, paragraph (b) is replaced by the shorter form held in
|
||||
* `marketing/drafts/privacy-page.md` §"Contingency" in the same commit that
|
||||
* makes it true.
|
||||
* `sendDefaultPii = true`, and there is no off switch in Settings. The opt-in
|
||||
* build change is merged on The-Nook master (FRE-355, 6e74b261) but no release
|
||||
* tag carries it yet, so the page must keep the always-on form until the first
|
||||
* release that contains it — then paragraph (b) is replaced by the shorter
|
||||
* form held in `marketing/drafts/privacy-page.md` §"Contingency" in the same
|
||||
* commit that makes it true.
|
||||
*
|
||||
* 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";
|
||||
@@ -29,17 +37,19 @@ export default function NookPrivacyPolicy() {
|
||||
<SubdomainHeader />
|
||||
<div class="min-h-screen px-[8vw] py-[10vh]">
|
||||
<div class="py-4 text-xl">The Nook's Privacy Policy</div>
|
||||
<div class="py-2">Last Updated: October 29, 2026</div>
|
||||
<div class="py-2">Last Updated: November 4, 2026</div>
|
||||
<div class="py-2">
|
||||
The Nook runs on your Mac. Your prompts, your code and your agent
|
||||
sessions are processed on your device. This page lists every
|
||||
connection the app makes over the network, what each one sends, and
|
||||
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> What leaves your Mac
|
||||
<span class="-ml-4 pr-2">1.</span> What leaves your devices
|
||||
</div>
|
||||
<div class="pl-4">
|
||||
<div class="pb-2">
|
||||
@@ -48,37 +58,44 @@ export default function NookPrivacyPolicy() {
|
||||
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 so you can recognize the Mac among
|
||||
your activations. 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's UUID. If you add an email during
|
||||
the trial, that request carries the email and the UUID, and it
|
||||
is sent once. All of these calls fail open: with no connection,
|
||||
the app keeps working, because license verification itself is
|
||||
offline.
|
||||
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'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:</div> Crash
|
||||
reports, error events, hang reports and performance traces are
|
||||
sent to Sentry, our crash-reporting processor, and this is on
|
||||
for every launch in this version — there is no setting that
|
||||
turns it off. Each report carries the app version, the macOS
|
||||
version, the Mac model and what the app was doing when it
|
||||
failed, and Sentry also receives your IP address and your macOS
|
||||
username. Reports never include your prompts, your code or your
|
||||
reports, error events, hang reports, session pings, and
|
||||
performance traces are sent to Sentry, our crash-reporting
|
||||
processor, and this is on for every launch in this version —
|
||||
there is no setting that turns it off. Each report carries the
|
||||
app version, the macOS version, the Mac model and what the app
|
||||
was doing when it failed, and Sentry also receives your IP
|
||||
address. Reports 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. When you turn it
|
||||
on, your Mac registers 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.
|
||||
The relay can see which devices are connected, when, and how
|
||||
much traffic they exchange.
|
||||
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
|
||||
@@ -131,16 +148,26 @@ export default function NookPrivacyPolicy() {
|
||||
</div>
|
||||
<div class="pb-2">
|
||||
<div class="-ml-6">(j) What does not leave your Mac:</div> The
|
||||
hook and the bridge that connect your agents to The Nook talk to
|
||||
nothing but your Mac — the hook dials the local bridge socket,
|
||||
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; 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.
|
||||
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">The iPhone companion.</div> The iPhone and
|
||||
Apple Watch app is in TestFlight beta. It runs the same Sentry
|
||||
reporting: the app version, iOS version, iPhone model, session
|
||||
pings and your IP address, with the same no-off-switch. 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>
|
||||
@@ -164,10 +191,12 @@ export default function NookPrivacyPolicy() {
|
||||
</div>
|
||||
<div class="pb-2 pl-4">
|
||||
License keys are signed and verified with Ed25519 and stored in
|
||||
the macOS Keychain. Phone traffic is encrypted end-to-end with
|
||||
keys your own devices generate at pairing; our relay holds no key
|
||||
that can read it. Every connection described on this page uses
|
||||
TLS.
|
||||
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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user