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