From 30fdc9d80693c846a9686e775374c2ae482c7a2a Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Thu, 11 Jun 2026 00:56:28 +0530 Subject: [PATCH] fix(copy): correct fabricated/stale details found in display-accuracy audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Display-detail accuracy sweep against prod reality (plans.yaml, live /openapi.json, prod k8s config, provisioner naming, GitHub/npm): - MarketingPage mock provision visual: region "iad-1 · us-east" was a fabricated region we never ran in — prod is DigitalOcean nyc3 (US-East). "postgres 16.2" → "postgres 16" (prod image is pgvector pg16; the patch level was invented). STEP-01 "202 accepted" → "201 created" (/db/new provisions synchronously and returns 201 per openapi.json; 202 belongs to /deploy/new + /stacks/new). - MarketingPage service-count copy: "Seven services" headline sat above EIGHT rendered cards and "Seven provisioning tools" omitted vector — both stale since /vector/new + mcp create_vector shipped 2026-05-20. Test now derives the expected count word from the rendered cards (rule 18: registry-iterating, not hand-typed). - MarketingPage claim-card sample URL: u_/d_ prefixes → the provisioner's canonical usr_/db_ scheme. - ForAgentsPage playground response ("what hits the wire — no mocks"): host "shared-1.instanode.dev" never existed → pg.instanode.dev (POSTGRES_PUBLIC_HOST); token "res_…" → UUID (openapi format:uuid); u_ → usr_; response meta "200" → "201". - StatusPage: github.com/instanode is an unrelated third-party org → github.com/InstaNode-dev. Verified accurate (no change needed): all tier prices/limits on Marketing/Pricing/Billing/PricingGrid vs plans.yaml; Team = contact-sales only; cancel/downgrade = support-only copy; *.deployment.instanode.dev; pg.instanode.dev terminal sample; nyc3 changelog entry. Known gap reported separately (not fixable here): `instanode-mcp` is not published on npm (404) while /for-agents + homepage instruct `npx -y instanode-mcp` — operator must publish mcp v0.12.0. Co-Authored-By: Claude Fable 5 --- src/pages/ForAgentsPage.test.tsx | 14 ++++++++ src/pages/ForAgentsPage.tsx | 14 ++++++-- src/pages/MarketingPage.test.tsx | 56 +++++++++++++++++++++++++------- src/pages/MarketingPage.tsx | 44 ++++++++++++++++++------- src/pages/StatusPage.tsx | 4 ++- 5 files changed, 105 insertions(+), 27 deletions(-) diff --git a/src/pages/ForAgentsPage.test.tsx b/src/pages/ForAgentsPage.test.tsx index 2f74822..5e1b7fe 100644 --- a/src/pages/ForAgentsPage.test.tsx +++ b/src/pages/ForAgentsPage.test.tsx @@ -42,6 +42,20 @@ describe('ForAgentsPage', () => { expect(cta).toBeTruthy() }) + it('playground response sample matches the real /db/new wire shape (2026-06-11 display-detail audit)', () => { + renderPage() + const text = document.body.textContent ?? '' + // The page promises "what hits the wire — no mocks": the public host is + // pg.instanode.dev (POSTGRES_PUBLIC_HOST) — "shared-1.instanode.dev" + // never existed — and role/db names use the provisioner's canonical + // usr_/db_ prefixes. /db/new returns 201 (synchronous), not 200. + expect(text).toContain('@pg.instanode.dev:5432') + expect(text).not.toContain('shared-1.instanode.dev') + expect(text).toContain('postgres://usr_') + expect(text).not.toContain('"res_') + expect(text).toContain('201 · 1.4s · application/json') + }) + it('copies the command and flips the button label to "copied"', async () => { copyMock.mockResolvedValue(true) renderPage() diff --git a/src/pages/ForAgentsPage.tsx b/src/pages/ForAgentsPage.tsx index 84f600d..51d4bf6 100644 --- a/src/pages/ForAgentsPage.tsx +++ b/src/pages/ForAgentsPage.tsx @@ -67,10 +67,16 @@ const PLAYGROUND_CURL = `curl -X POST https://api.instanode.dev/db/new \\ // provisioning response (CLAUDE.md convention #11) — a caller that omits // `env` lands in `development`, the lowest-stakes bucket. The earlier // sample dropped it, so the page misrepresented the wire shape. +// Display-detail accuracy (2026-06-11): the page promises "what hits the +// wire — no mocks", so the shapes must match prod: `token` is a UUID +// (openapi DBProvisionResponse format:uuid, not the old fabricated +// "res_…"), the public host is pg.instanode.dev (POSTGRES_PUBLIC_HOST; +// "shared-1.instanode.dev" never existed), and role/db names follow the +// provisioner's canonical usr_{token[:12]}/db_{token[:12]} scheme. const PLAYGROUND_RESPONSE = `{ "ok": true, - "token": "res_2RtL9k4mP", - "connection_url": "postgres://u_3jX:••••@shared-1.instanode.dev:5432/db_2rtL9k4mp", + "token": "9b2f61ce-4a3d-4e8b-b150-7c2f0a4d9e21", + "connection_url": "postgres://usr_9b2f61ce4a3d:••••@pg.instanode.dev:5432/db_9b2f61ce4a3d", "tier": "anonymous", "env": "development", "limits": { "storage_mb": 10, "connections": 2 }, @@ -172,7 +178,9 @@ export function ForAgentsPage() {
response - 200 · 1.4s · application/json + {/* Display-detail accuracy (2026-06-11): /db/new returns + 201 Created (synchronous provisioning), not 200. */} + 201 · 1.4s · application/json
{highlightJson(PLAYGROUND_RESPONSE)}
diff --git a/src/pages/MarketingPage.test.tsx b/src/pages/MarketingPage.test.tsx index 454534e..20086fc 100644 --- a/src/pages/MarketingPage.test.tsx +++ b/src/pages/MarketingPage.test.tsx @@ -88,26 +88,60 @@ describe('MarketingPage — homepage nav drift (T18 P1-2)', () => { }) describe('MarketingPage — claim consistency (T18 P1-4 / P1-6)', () => { - it("'Seven services' headline matches the MCP tools card (both say seven, listing webhook)", () => { + it('services headline + MCP tools card count match the rendered SERVICES cards (registry-derived, not hand-typed)', () => { const { container } = render( , ) const text = container.textContent ?? '' - // Headline says "Seven services. One bundle." - expect(text).toMatch(/Seven services\. One bundle\./) - // MCP tools card lists the seven provisioning tools (must still list - // webhook — anti-regression for the dropped-webhook bug) AND, per the - // 2026-06-03 gap fix, also surfaces the stack/deployment management tools - // (the MCP server registers more than seven; "Seven tools registered" was - // an understatement). - expect(text).not.toMatch(/Six provisioning tools/) - expect(text).toMatch(/Seven provisioning tools/) - expect(text).toMatch(/webhook/) + // 2026-06-11 display-detail audit: the headline said "Seven services" + // above EIGHT rendered cards (vector joined SERVICES on 2026-05-20 but + // the count copy was never bumped), and the MCP card said "Seven + // provisioning tools" while omitting `vector` (mcp registers + // create_vector). Per rule 18, derive the expected count from the live + // registry (the rendered service cards) instead of a hand-typed word so + // adding service #9 without bumping the copy fails this test. + const cardCount = container.querySelectorAll('.mkt-service-card').length + expect(cardCount).toBeGreaterThan(0) + const COUNT_WORDS = [ + 'Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', + 'Nine', 'Ten', 'Eleven', 'Twelve', + ] + const word = COUNT_WORDS[cardCount] + expect(word).toBeDefined() + expect(text).toContain(`${word} services. One bundle.`) + expect(text).toContain(`${word} provisioning tools`) + // The MCP tools card must list every provisioning service shown in the + // cards row — anti-regression for the dropped-webhook (T18 P1-4) and + // dropped-vector (2026-06-11) bugs — plus the management tools. + for (const svc of ['postgres', 'vector', 'redis', 'mongo', 'queue', 'storage', 'webhook', 'deploy']) { + expect(text).toContain(svc) + } expect(text).toMatch(/list_deployments/) }) + it('mock provision visual shows real prod facts: nyc3 region, 201 for /db/new, usr_/db_ name prefixes', () => { + const { container } = render( + + + , + ) + const html = container.innerHTML + // 2026-06-11 display-detail audit: prod runs on DigitalOcean nyc3 — + // "iad-1" was a fabricated region we never ran in. + expect(html).toContain('nyc3 · us-east') + expect(html).not.toContain('iad-1') + // POST /db/new provisions synchronously → 201 Created (openapi.json); + // "202 accepted" belongs to /deploy/new + /stacks/new only. + expect(html).toContain('201 created') + expect(html).not.toContain('202 accepted') + // Claim-card sample URL uses the provisioner's canonical usr_/db_ + // prefixes, not the fabricated u_/d_ ones. + expect(html).toContain('usr_xY9') + expect(html).not.toContain('postgres://u_xY9') + }) + it("Deploy service card claims a build window consistent with content/llms.txt (~60s, not '<10s')", () => { const { container } = render( diff --git a/src/pages/MarketingPage.tsx b/src/pages/MarketingPage.tsx index 89883c4..faeb81c 100644 --- a/src/pages/MarketingPage.tsx +++ b/src/pages/MarketingPage.tsx @@ -383,11 +383,15 @@ export function MarketingPage() { - {/* ---------- seven services row ---------- */} + {/* ---------- eight services row ---------- */}
-
Seven services. One bundle.
+ {/* Display-detail accuracy (2026-06-11): Vector (pgvector, /vector/new) + joined the SERVICES array on 2026-05-20 but this headline kept + saying "Seven" above eight rendered cards. The count below is + asserted against SERVICES.length in MarketingPage.test.tsx. */} +
Eight services. One bundle.

The whole stack, not the pieces.

@@ -447,7 +451,11 @@ export function MarketingPage() {
authnone — fingerprinted
body{'{}'}
- status202 accepted + {/* Display-detail accuracy (2026-06-11): POST /db/new provisions + synchronously and returns 201 Created (see /openapi.json) — + the old "202 accepted" implied an async contract the db + endpoint does not have (202 is /deploy/new + /stacks/new). */} + status201 created
@@ -460,8 +468,14 @@ export function MarketingPage() { stored credentials, a connection string in 1.4 s. 24 h TTL on the free tier.

diff --git a/src/pages/StatusPage.tsx b/src/pages/StatusPage.tsx index 2a4693a..1128f62 100644 --- a/src/pages/StatusPage.tsx +++ b/src/pages/StatusPage.tsx @@ -136,7 +136,9 @@ export function StatusPage() { {/* FIX-G (2026-05-14): "Subscribe via RSS" link removed — /status.rss 404s on the API. See IncidentsPage for the matching cleanup. */}
- GitHub status + {/* Display-detail accuracy (2026-06-11): github.com/instanode is an + unrelated third-party org — ours is InstaNode-dev. */} + GitHub status · Incident log