From 6ff31346ff20a60a4f19c4ec5996932c8472d72a Mon Sep 17 00:00:00 2001
From: agent-cto
Date: Wed, 4 Nov 2026 00:30:21 +0000
Subject: [PATCH] =?UTF-8?q?site:=20restore=20the=20remote=20SSH=20copy=20?=
=?UTF-8?q?=E2=80=94=20HELD,=20do=20not=20merge=20(FRE-997,=20remote=20hal?=
=?UTF-8?q?f)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DO NOT MERGE OR DEPLOY THIS BRANCH. It is the held half of FRE-997, split out
of a336a6c at the Code Review Engineer's changes-requested verdict and the
Chief of Staff's 2026-11-03 launch hold (comment 2ccad154), and it is stacked
on `freno-dev/FRE-997-count-18` so its own diff stays remote-only.
The copy it restores was pulled by FRE-323 (c1c498e, c718370). FRE-997's
argument is that those removals were checked against claims the copy never
made: hosts come from `~/.ssh/config` and Tailscale (`RemoteHostDiscovery`),
the one-time `ssh-copy-id` is a prerequisite the row hands the user as a
command (`RemoteHostStatus.fixCommand`), the per-host credential is minted and
copied over (`RemoteMirror`), and a remote host mirrors this Mac's integrations
(`RemoteMirrorReconcile`). Two things in the old copy were genuinely wrong and
are fixed rather than restored: the "every hooked agent" overstatement (Muse,
Cline and Amp are `.unsupported` for remote and are named) and the count.
It may land only when all of these are recorded on FRE-997:
1. a CTO verdict that the one-click flow was run on the shipping build;
2. footage of a remote agent joining the island;
3. the Chief of Staff revising the FRE-346 §3 launch gate and taking the
public-claim call to the sponsor.
Until then the live site keeps the FRE-323 state. The restore condition this
commit deletes (`marketing/drafts/remote-ssh/copy.md`) is the gate being cited:
FRE-205 is todo/unassigned, FRE-320 is a verdict task, and no recording exists.
- The Remote collage tile and its mock.
- The "Any SSH box, one click away" breakdown with its RemoteHostDemo.
- The "One-click SSH setup" chip.
- The /agents remote paragraph and the Cline/Amp "this Mac only" rows.
- The approvals bullet names the three local-only agents instead of claiming
every hooked agent.
- remote-claims.test.ts guards the restored copy plus the two overstatements
that must not return.
- positioning.md moves remote SSH to publishable with its backing.
Gate on this branch, this run: `bun test src/routes/nook` 17 pass / 0 fail;
`bun run build` succeeds. Green tests do not lift the hold.
---
marketing/drafts/remote-ssh/copy.md | 79 ------------
marketing/drafts/remote-ssh/rationale.md | 30 -----
marketing/positioning.md | 33 +++--
src/components/nook/FeatureBreakdowns.tsx | 125 +++++++++++++++++-
src/components/nook/FeatureCollage.tsx | 50 +++++++-
src/components/nook/IslandExtras.tsx | 1 +
src/routes/nook/agents.test.ts | 21 +++
src/routes/nook/agents.tsx | 10 +-
src/routes/nook/remote-claims.test.ts | 148 ++++++++++------------
9 files changed, 288 insertions(+), 209 deletions(-)
delete mode 100644 marketing/drafts/remote-ssh/copy.md
delete mode 100644 marketing/drafts/remote-ssh/rationale.md
diff --git a/marketing/drafts/remote-ssh/copy.md b/marketing/drafts/remote-ssh/copy.md
deleted file mode 100644
index b7a449f..0000000
--- a/marketing/drafts/remote-ssh/copy.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# Remote SSH copy — HELD, do not publish
-
-**Status:** removed from the `freno-dev` source on 2026-10-29 in the FRE-323
-correction, and **not yet off the live site** — the deploy is blocked on a write
-credential to `mikefreno/freno-dev` (card `82d1e1b7`). `nook.freno.me` still
-serves every sentence below until that push or a Vercel deploy lands.
-**Owner:** CMO. **Verified by:** CTO, on the FRE-320/FRE-205 work.
-**Restore only when:** FRE-320/FRE-205 ship a genuinely one-click install, the CTO
-verifies that flow, and a recording shows a remote agent joining the island.
-Until then this file is the only home for these sentences.
-
-## What was removed
-
-### 1. Landing collage tile
-
-Source: `src/components/nook/FeatureCollage.tsx` (removed 2026-10-29).
-
-```
-kicker: Remote
-title: Agents on other machines
-body: Run agents on Linux boxes and SSH servers — one click installs the
- nook-hook, and their sessions join the same island.
-```
-
-The mock attached to it showed two session rows whose agent chips named
-`build-box` and `gpu-rig`.
-
-### 2. Landing feature breakdown section
-
-Source: `src/components/nook/FeatureBreakdowns.tsx` (removed 2026-10-29).
-
-```
-kicker: Remote
-title: Any SSH box, one click away
-body: Pick a host from your ssh config or your tailnet and click once — the
- nook-hook installs itself and its agents appear beside your local ones,
- indistinguishable.
-
-bullets:
-- One click: connect, push the hook, configure agents, check it can reach this Mac
-- Hosts mirror this Mac's installed integrations automatically
-- Remote sessions are ordinary rows; the agent chip names the machine
-```
-
-The section's demo animated a `gpu-rig` host moving from "Not set up" through
-`connecting` → `pushing the hook binary` → `configuring agents` → `checking the
-host can reach this Mac` → `Live`, then showed a remote session row.
-
-### 3. Approvals bullet
-
-Source: `src/components/nook/FeatureBreakdowns.tsx` (removed 2026-10-29).
-
-```
-- Works across every hooked agent, local or remote
-```
-
-### 4. Feature chip
-
-Source: `src/components/nook/IslandExtras.tsx` (removed 2026-10-29).
-
-```
-One-click SSH setup
-```
-
-## What replaced it
-
-Nothing. The Remote tile and section were removed rather than replaced; the
-existing Approvals cell already carries the verified local claim:
-
-> Approve an agent's tool call from your Mac's notch, and the agent carries on.
-
-## Restore checklist
-
-1. FRE-320/FRE-205 have shipped the one-click install and removed the
- `~/.ssh/config` / `ssh-copy-id` friction described in FRE-320.
-2. The CTO has verified the shipping flow and the evidence is on FRE-320.
-3. A recording exists showing a remote agent joining the island.
-4. CMO restores the copy above, then owns the launch plan for it — with an
- owner and date per item — before anything goes back on the site.
diff --git a/marketing/drafts/remote-ssh/rationale.md b/marketing/drafts/remote-ssh/rationale.md
deleted file mode 100644
index 104c08b..0000000
--- a/marketing/drafts/remote-ssh/rationale.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Why the remote claim is parked
-
-The site was selling a setup path a buyer does not get.
-
-FRE-320 measured today's actual path (2026-10-29): the one-click flow is
-app-UI-only, needs a hand-edited `~/.ssh/config` for any host not already in ssh
-config or on the tailnet, needs a one-time `ssh-copy-id` because the app runs ssh
-with `BatchMode=yes`, and has no manual fallback for minting the per-host
-credential. FRE-315 and FRE-322 §3 correction 4 marked the remote claim
-unverified and demo-gated. The CTO named it the largest launch risk because it
-was already in front of buyers.
-
-So the `freno-dev` source now says only what the product can back today: local
-agents, the card, and the notch. That correction is committed locally and is
-**not deployed** — the live page still carries the remote sentences until the
-push in FRE-323 card `82d1e1b7` lands. The remote story is not deleted — it is
-parked here with the FRE-320/FRE-205 work so it can return the day the one-click
-install ships and is recorded.
-
-## What has to be true before it returns
-
-| Requirement | Owner | Date |
-|---|---|---|
-| One-click install ships without hand-edited `~/.ssh/config` or `ssh-copy-id` | FRE-320/FRE-205 engineering | When FRE-320/FRE-205 ships |
-| CTO verifies the shipping flow and records the evidence on FRE-320 | CTO | Same day, before any copy moves |
-| A recording shows a remote agent joining the island | Sponsor/CMO | Before restore |
-| Restore copy and rebuild the launch plan with an owner + date per item | CMO | Day the three rows above are true |
-
-Nothing in this folder is publishable. `marketing/approved/` remains the only
-place a human publishes from.
diff --git a/marketing/positioning.md b/marketing/positioning.md
index 0922cf7..9864972 100644
--- a/marketing/positioning.md
+++ b/marketing/positioning.md
@@ -4,13 +4,13 @@ Every drafted asset draws its voice, claims, and constraints from this file. If
artifact invents its own framing, fix the artifact or fix this file — never both
silently diverging.
-**Reconciled 2026-10-29**, and again **2026-11-03** for the FRE-997 count
-correction, against the CTO's verdicts ([FRE-315], [FRE-322], [FRE-354],
-[FRE-997]), the Chief of Staff's price decision (2026-10-29 04:01), the Plan B
-launch route ([FRE-346] → [FRE-203] `plan-b`), and `The-Nook` master (app floor is
-**14.2**, not 14.0 — `freno-dev` `881190d`, site merge `134f41e`). The previous
-version of this file named an upstream `the-nook/docs/marketing-strategy.md` that
-no longer exists; the verdicts below are the source of truth it was pointing at.
+**Reconciled 2026-10-29**, and again **2026-11-03** for the FRE-997 correction,
+against the CTO's verdicts ([FRE-315], [FRE-322], [FRE-354], [FRE-997]), the Chief
+of Staff's price decision (2026-10-29 04:01), the Plan B launch route ([FRE-346] →
+[FRE-203] `plan-b`), and `The-Nook` master (app floor is **14.2**, not 14.0 —
+`freno-dev` `881190d`, site merge `134f41e`). The previous version of this file
+named an upstream `the-nook/docs/marketing-strategy.md` that no longer exists; the
+verdicts below are the source of truth it was pointing at.
[FRE-315]: https://paperclip.freno.me/FRE/issues/FRE-315
[FRE-322]: https://paperclip.freno.me/FRE/issues/FRE-322
@@ -115,11 +115,16 @@ one thing forbidden: say "TestFlight beta" when the phone exists in a sentence a
all, and never claim approvals-from-phone as a shipped capability without its own
CTO verdict — no "(coming soon)" parentheticals either way.
-Remote SSH is **held**, not approved: the one-click install has not
-been verified end to end ([FRE-315] §1) and the shipped path needs hand-edited
-`~/.ssh/config` and a one-time `ssh-copy-id` ([FRE-320]). Its copy stays parked in
-`marketing/drafts/remote-ssh/` until the CTO verifies the shipping flow **and** a
-recording shows a remote agent joining the notch.
+Remote SSH is **publishable**, and the site sells it again ([FRE-997]). The
+copy that was pulled on 2026-10-29 had been checked against claims it never made:
+hosts come from `~/.ssh/config` and Tailscale (`RemoteHostDiscovery`), the
+one-time `ssh-copy-id` is a prerequisite the row hands the user as a command
+(`RemoteHostStatus.fixCommand`), the per-host credential is minted and copied
+over (`RemoteMirror`), and a remote host mirrors this Mac's integrations
+(`RemoteMirrorReconcile`). Two things in the old copy were wrong and were fixed
+rather than restored: the "every hooked agent" overstatement, and a count that
+said thirteen against a registry of eighteen. Muse, Cline and Amp are
+`.unsupported` for remote in `AgentSpec.remote`, and the copy names them.
### 5. Humans hold every account
@@ -138,9 +143,9 @@ Each row names the evidence, not a feeling. Re-read the verdict before using a r
| The hook and bridge are not a cloud service | **Verified code fact, held on disclosure** | [FRE-322] §2, wording corrected by [FRE-354] `(j)`. Held until Sentry is gated/removed and `/privacy` + `/faq` land. Never widen to "The Nook", never "nothing but your Mac". |
| Fan, thermal and charge control | **No claim verdict yet — do not lead with it** | Backed by `helper/` (privileged helper, SMC, no kext), but no CTO sentence exists for it. Documentary, not launch. |
| One-time purchase, no subscription | **Publishable fact, price not a launch asset** | $10, held at $10. No dated rise, no discount framing, no pricing copy. |
-| Agent coverage numbers ("eighteen agents", "18 agents") | **Publishable at 18** | [FRE-997]: the /agents table now lists every row of `AgentSpec.all` and `agents.test.ts` asserts equality with the 18-name registry in registry order, so the landing bullet, the marquee chip and the /agents copy say 18. No other number is publishable. |
+| Agent coverage numbers ("eighteen agents", "18 agents") | **Publishable at 18** | [FRE-997]: the /agents table now lists every row of `AgentSpec.all` and `agents.test.ts` asserts equality with the 18-name registry in registry order, so the landing bullet, the marquee chip and the /agents copy say 18. No other number is publishable, and `every` / `all` are still banned without naming the three local-only agents. |
| macOS 14.2 or later | **Publishable fact** | The app cannot start below 14.2 (`freno-dev` `881190d`, site `134f41e`). "macOS 14+" is false and was fixed on the site. |
-| Remote agents over SSH, one click to install | **Held** | [FRE-315] §1, [FRE-320], [FRE-323]. Needs a verified one-click install plus a recording. |
+| Remote agents over SSH, one click to install | **Publishable, with the three local-only agents named** | [FRE-997]: `RemoteHostDiscovery` (ssh config + tailnet), `RemoteMirror` (hook push, credential, mirroring), `RemoteMirrorReconcile`, `RemoteHostStatus.fixCommand` (the one-time `ssh-copy-id` the row shows). `AgentSpec.remote` is `.unsupported` for Muse, Cline and Amp — the landing bullet and /agents paragraph name them; never say "every hooked agent". |
| "Nothing leaves your Mac", "no telemetry", "local-only", "no account" | **False today — banned** | Sentry unconditional, licence check with hardware fingerprint ([FRE-322] §2.4). |
| Approvals from the iPhone or Apple Watch | **No verdict — not a launch claim** | The companion is a TestFlight beta ([FRE-354]); the approval-from-phone claim has no CTO verdict and stays out of launch copy. |
diff --git a/src/components/nook/FeatureBreakdowns.tsx b/src/components/nook/FeatureBreakdowns.tsx
index fa1d546..220cec2 100644
--- a/src/components/nook/FeatureBreakdowns.tsx
+++ b/src/components/nook/FeatureBreakdowns.tsx
@@ -1,5 +1,6 @@
import {
For,
+ Show,
createEffect,
createSignal,
onCleanup,
@@ -20,6 +21,7 @@ import { Campfire, type CampfireState } from "./Campfire";
import {
ApprovalCardMock,
SessionRowMock,
+ Glyph,
CLAUDE,
CODEX
} from "./ModuleMocks";
@@ -35,7 +37,7 @@ import {
* Detailed feature breakdowns: alternating copy + live-demo sections.
* Each demo stages the real interaction loop: attention flares, approval
* resolves, fans throttle, the charge ceiling holds, meetings surface,
- * the camera wakes. Newer demos live in
+ * the camera wakes, a remote host goes live. Newer demos live in
* MoreDemos.tsx; app-anatomy pieces in ModuleMocks.tsx.
*/
@@ -805,6 +807,112 @@ function CameraDemo() {
);
}
+/* ── Demo 7: Settings ▸ Remote hosts — one click to Live ──────────── */
+
+/** RemoteMirror's progress steps, in order. */
+const SETUP_STEPS = [
+ "connecting",
+ "pushing the hook binary",
+ "configuring agents",
+ "checking the host can reach this Mac"
+];
+
+function RemoteHostDemo() {
+ /* -1 not set up · 0…3 setting up · 4 live */
+ const [step, setStep] = createSignal(-1);
+ const [pressed, setPressed] = createSignal(false);
+ useDemoLoop(11000, [
+ [0, () => (setStep(-1), setPressed(false))],
+ [1400, () => setPressed(true)],
+ [1700, () => (setPressed(false), setStep(0))],
+ [2700, () => setStep(1)],
+ [3700, () => setStep(2)],
+ [4700, () => setStep(3)],
+ [5800, () => setStep(4)]
+ ]);
+ const live = () => step() === 4;
+ const working = () => step() >= 0 && step() < 4;
+ const chip = () =>
+ live()
+ ? { color: "rgb(48,209,88)", label: "Live" }
+ : working()
+ ? { color: "rgba(255,255,255,0.55)", label: "Setting up" }
+ : { color: "rgba(255,255,255,0.35)", label: "Not set up" };
+
+ return (
+
+ {/* the host's card in Settings ▸ Agents ▸ Remote hosts */}
+
+
+
+
+
gpu-rig
+
tailnet peer
+
+
+
+
+
+
+ {chip().label}
+
+
+ Set up
+
+ }
+ >
+
+
+ Remove
+
+
+
+
+ {working() ? SETUP_STEPS[step()] : " "}
+
+
+
+
+ {/* its agents arrive as ordinary rows, the machine named in the chip */}
+
+
+
+
+
+ );
+}
+
/* ── Demo 8: campfire states ───────────────────────────────────────── */
function CampfireDemo() {
@@ -868,6 +976,7 @@ export default function FeatureBreakdowns() {
"Approval cards pin above the session list; questions answer inside their row",
"Allow for session waves through the rest of that session's requests",
"Answer from iPhone or Apple Watch too, now in TestFlight beta",
+ "Works across local and remote sessions; Muse, Cline and Amp are this Mac only"
]}
reversed
>
@@ -887,6 +996,20 @@ export default function FeatureBreakdowns() {
+
+
+
+
+
+
+
+ );
+}
+
/* Deterministic usage wander for the traces. */
const wander = (n: number, k: number) =>
0.42 + 0.22 * Math.sin(n * 0.45 + k * 1.7) + 0.12 * Math.sin(n * 1.3 + k);
@@ -221,6 +256,19 @@ export default function FeatureCollage() {
+ {/* Remote agents */}
+
+
+
+
+
+
+
+
{/* Gauges */}
{
expect(COPY).not.toContain("all thirteen");
});
});
+
+describe("Nook /agents remote coverage", () => {
+ it("says agents can run on remote machines over SSH", () => {
+ expect(PROSE).toContain("remote machines");
+ expect(PROSE).toContain("remote sessions report into the same grid");
+ });
+
+ it("names the three agents that stay on this Mac", () => {
+ expect(PROSE).toContain("Muse, Cline and Amp run on this Mac only");
+ });
+
+ it("discloses the local-only rows where they are listed", () => {
+ const localOnly = [
+ ...SOURCE.matchAll(/This Mac only — remote hosts skip it/g)
+ ];
+ expect(localOnly.length).toBe(3);
+ });
+});
diff --git a/src/routes/nook/agents.tsx b/src/routes/nook/agents.tsx
index ccc2672..7a104aa 100644
--- a/src/routes/nook/agents.tsx
+++ b/src/routes/nook/agents.tsx
@@ -209,7 +209,8 @@ const AGENTS: AgentEntry[] = [
},
{
name: "Cline",
- wiring: "One hook file per event in its hooks directory",
+ wiring:
+ "One hook file per event in its hooks directory. This Mac only — remote hosts skip it",
events: [
"SessionStart",
"SessionEnd",
@@ -334,7 +335,8 @@ const AGENTS: AgentEntry[] = [
},
{
name: "Amp",
- wiring: "In-process extension package",
+ wiring:
+ "In-process extension package. This Mac only — remote hosts skip it",
events: [
"SessionStart",
"SessionEnd",
@@ -387,7 +389,9 @@ export default function NookAgentsPage() {
Each agent reports its own set of events. "Allow / Deny from a card"
means the agent hands the decision to The Nook while it waits;
"Observe" means every event still appears live, but the agent keeps
- its own prompting.
+ its own prompting. Agents can run on this Mac or on remote machines
+ over SSH — remote sessions report into the same grid. Muse, Cline and
+ Amp run on this Mac only.
diff --git a/src/routes/nook/remote-claims.test.ts b/src/routes/nook/remote-claims.test.ts
index 9dee6fd..8280f6b 100644
--- a/src/routes/nook/remote-claims.test.ts
+++ b/src/routes/nook/remote-claims.test.ts
@@ -1,41 +1,27 @@
/**
- * Regression test for the removed remote / SSH claims and the removed agent
- * count (FRE-323, FRE-359 verdict B).
+ * Guard for the remote / SSH story on the Nook site, and for the two phrasings
+ * that must not come back with it (FRE-323 → FRE-997).
*
- * FRE-323 took the remote story off the site because it was unverified and
- * demo-gated (FRE-315, FRE-320, FRE-322 §3 correction 4): the "one click
- * installs the nook-hook" flow is app-UI-only, needs a hand-edited
- * `~/.ssh/config` for any host not already in ssh config or on the tailnet,
- * needs a one-time `ssh-copy-id` because the app runs ssh with
- * `BatchMode=yes`, and has no manual fallback for minting the per-host
- * credential. FRE-359 verdict B removed the coverage count for the same
- * reason: the /agents table lists 13 of the registry's 18 rows.
+ * FRE-323 removed the remote copy because it had been checked against claims
+ * the copy never made: the app does list hosts from `~/.ssh/config` and
+ * Tailscale, a one-time `ssh-copy-id` is a normal prerequisite the row explains,
+ * and the per-host credential is minted and copied automatically
+ * (`RemoteHostDiscovery`, `RemoteHostStatus.fixCommand`, `RemoteMirror`). Two
+ * things in the old copy were genuinely wrong, and this file guards those
+ * instead of the copy as a whole:
*
- * FRE-997 corrects the second half without touching the first. The count was
- * stale, not unverifiable: `AgentSpec.all` holds eighteen, /agents now lists
- * all eighteen and `agents.test.ts` asserts that roster as an equality again.
- * So the two completeness phrasings FRE-359 banned ("every coding agent",
- * "Supported agents") no longer rest on a 13-of-18 gap — the ban existed
- * because the page claimed the set and listed two thirds of it. They are out
- * of `BANNED_COVERAGE` on this branch for that reason alone; the stale counts
- * stay banned, and every FRE-323 remote sentence stays banned, because this
- * branch still carries the FRE-323 site state.
+ * - "Works across every hooked agent, local or remote" overstated it. Muse,
+ * Cline and Amp are `.unsupported` for remote in `AgentSpec.remote`, so the
+ * landing bullet and the /agents paragraph name them.
+ * - The count said thirteen while `AgentSpec.all` holds eighteen. The fix was
+ * to say eighteen, not to drop the count.
*
- * The copy was not thrown away — it is parked in
- * `marketing/drafts/remote-ssh/` with the restore gate, and this test asserts
- * it is still there so nobody deletes the parked story as stale. It goes back
- * on the site only when the one-click install ships and is recorded.
+ * So the removal guards from `d44133f` are gone: a removed sentence is exactly
+ * what this task restores. What stays is the pair of bans, because either one
+ * coming back would repeat the original defect.
*
* STATIC SOURCE AUDIT, the same pattern as `agents.test.ts` and
* `downloads.test.ts` (SolidJS does not render under `bun:test`).
- *
- * Deliberate exceptions, not audited here — both were weighed with the Chief
- * of Staff at the go/no-go and left in place on purpose:
- * - `src/routes/nook/agents.tsx` Muse row: "This Mac only — remote hosts skip
- * it" is a limitation disclosure, not a capability claim.
- * - `src/components/nook/IslandExtras.tsx` "Tailscale hosts" chip: adjacent to
- * the removed remote story, but tailnet host lookup does exist. Raised on
- * FRE-323 rather than widened into this correction.
*/
import { describe, it, expect } from "bun:test";
import { readFileSync } from "node:fs";
@@ -43,7 +29,7 @@ import { join } from "node:path";
const ROOT = join(import.meta.dir, "../../..");
-/** Shipped page and component source. Tests and drafts may quote the old copy. */
+/** Shipped page and component source. */
const AUDITED = [
"src/routes/nook/index.tsx",
"src/routes/nook/agents.tsx",
@@ -53,27 +39,15 @@ const AUDITED = [
"src/components/nook/IslandExtras.tsx"
];
-/** Every sentence FRE-323 ordered off the site. */
+/** The overstatements the restored copy must never carry again. */
const BANNED_REMOTE_CLAIMS = [
- "Agents on other machines",
- "one click installs the nook-hook",
- "Any SSH box",
- "Works across every hooked agent, local or remote",
- "Remote sessions are ordinary rows",
- "One-click SSH setup",
- "remote machines over SSH",
- "this Mac or remote machines"
-];
-
-/** FRE-359 verdict B: no stale count, in any form.
- *
- * "every coding agent" and "Supported agents" left this list with FRE-997:
- * the page now lists all eighteen registry rows and `agents.test.ts` asserts
- * that equality, so the completeness claim is backed rather than incomplete. */
-const BANNED_COVERAGE = [
+ // a universal claim: three registry agents cannot mirror over SSH
+ "every hooked agent, local or remote",
+ "Works across every hooked agent",
+ // the stale count this task replaced
+ "13 agents",
"all thirteen",
- "thirteen coding agents",
- "13 agents"
+ "thirteen coding agents"
];
/** User-facing copy only: comments are not copy and may name the old wording. */
@@ -83,9 +57,46 @@ function copyOf(file: string): string {
.replace(/^\s*\/\/.*$/gm, "");
}
-describe("remote claims stay off the site (FRE-323)", () => {
+describe("the restored remote copy is on the site (FRE-997)", () => {
+ it("the landing collage sells agents on other machines", () => {
+ const copy = copyOf("src/components/nook/FeatureCollage.tsx");
+ for (const phrase of [
+ "Agents on other machines",
+ "one click installs the nook-hook",
+ "Remote"
+ ]) {
+ expect(copy).toContain(phrase);
+ }
+ });
+
+ it("the landing breakdown keeps the SSH section and its demo", () => {
+ const copy = copyOf("src/components/nook/FeatureBreakdowns.tsx");
+ for (const phrase of [
+ "Any SSH box, one click away",
+ "Pick a host from your ssh config or your tailnet and click once",
+ "Remote sessions are ordinary rows",
+ "RemoteHostDemo"
+ ]) {
+ expect(copy).toContain(phrase);
+ }
+ });
+
+ it("the chip is back", () => {
+ expect(copyOf("src/components/nook/IslandExtras.tsx")).toContain(
+ "One-click SSH setup"
+ );
+ });
+
+ it("/agents says remote sessions report into the same grid", () => {
+ const copy = copyOf("src/routes/nook/agents.tsx");
+ expect(copy).toContain("remote machines");
+ expect(copy).toContain("remote sessions report into the same grid");
+ });
+});
+
+describe("the two original overstatements stay off the site (FRE-323, FRE-359)", () => {
for (const file of AUDITED) {
- it(`${file} does not restore a removed remote sentence`, () => {
+ it(`${file} claims no universal remote coverage and no stale count`, () => {
const copy = copyOf(file);
for (const phrase of BANNED_REMOTE_CLAIMS) {
expect(copy.toLowerCase()).not.toContain(phrase.toLowerCase());
@@ -93,34 +104,9 @@ describe("remote claims stay off the site (FRE-323)", () => {
});
}
- it("/agents no longer offers remote sessions", () => {
- const copy = copyOf("src/routes/nook/agents.tsx");
- expect(copy).not.toContain("remote sessions report into the same grid");
- expect(copy).not.toContain("on this Mac or on remote");
- });
-
- it("the parked copy still exists, so restoring the story is a revert and not a rewrite", () => {
- const parked = readFileSync(join(ROOT, "marketing/drafts/remote-ssh/copy.md"), "utf8");
- for (const phrase of ["Agents on other machines", "Any SSH box, one click away"]) {
- expect(parked).toContain(phrase);
- }
- expect(readFileSync(join(ROOT, "marketing/drafts/remote-ssh/rationale.md"), "utf8")).toContain(
- "FRE-320"
+ it("the landing names the agents that stay local", () => {
+ expect(copyOf("src/components/nook/FeatureBreakdowns.tsx")).toContain(
+ "Muse, Cline and Amp are this Mac only"
);
});
});
-
-describe("the agent count is corrected, not dropped (FRE-997)", () => {
- for (const file of AUDITED) {
- it(`${file} states no stale count`, () => {
- const copy = copyOf(file);
- for (const phrase of BANNED_COVERAGE) {
- expect(copy.toLowerCase()).not.toContain(phrase.toLowerCase());
- }
- });
- }
-
- it("/agents states the registry's size", () => {
- expect(copyOf("src/routes/nook/agents.tsx")).toContain("Supported agents");
- });
-});
--
2.49.1