Files
freno-dev/src/routes/nook/privacy.tsx
fixture 4d6550f0d1 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).
2026-11-04 14:50:41 +00:00

235 lines
12 KiB
TypeScript
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.
/**
* The Nook privacy policy — `nook.freno.me/privacy`.
*
* 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 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. 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";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader";
export default function NookPrivacyPolicy() {
return (
<>
<EdgeCacheHeaders maxAge={300} />
<PageHead
title="Privacy Policy"
description="Privacy policy for The Nook, a coding-agent orchestration and hardware control app."
/>
<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: November 4, 2026</div>
<div class="py-2">
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 devices
</div>
<div class="pl-4">
<div class="pb-2">
<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:</div> Crash
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. 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">(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">(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">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>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">2.</span> How We Use It
</div>
<div class="pb-2 pl-4">
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>
<div class="py-2">
<div class="pb-2 text-lg">
<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 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>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
</div>
<div class="pb-2 pl-4">
We may update this policy periodically. Any changes are posted on
this page, so please review it from time to time.
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">5.</span> Contact Us
</div>
<div class="pb-2 pl-4">
If you have any questions about this policy, you can contact us{" "}
<a
href={buildMainSiteUrl("/contact")}
target="_blank"
rel="noopener noreferrer"
class="text-blue hover-underline-animation"
>
here
</a>
.
</div>
</div>
</ol>
</div>
</>
);
}