From 51fd65784dc0c40ac4c9bfd6f76bd6cdb5c183d1 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 23 Oct 2026 02:31:52 +0000 Subject: [PATCH 1/2] Disclose Jam in the privacy policy and fix public copy (T14: SC-01, SE-03, SE-04, SE-05, AX-03) - Privacy policy (EN, ES, HU): new section 8, "Bug Reports with Jam", describing what C1 ships: Jam loads for every visitor after the first interaction or 8 s, what its frame receives, what a recording contains, that the signed-in account ID is attached, the processor, retention, and how to object. Data Sharing now names Jam, PostHog and Sentry. Date moves to October 23, 2026. - Guides: drop the internal "Can Google index private app pages?" FAQ. - Prep-mode counts come from the tool lists in tool-links.tsx (8 modes, 3 utilities) in the landing FAQ and pricing cards, the landing JSON-LD, the guides and llms.txt. The guide copy takes the Pro price from one constant, and the dead "Student plans" base entry for the pricing page is gone. - check-site fails the build on a skipped heading level. - Organization JSON-LD logo points at /icon-1024.png. Co-Authored-By: Claude Opus 5.5 --- docs/operations.md | 6 +-- docs/testing.md | 2 +- public/ai-debate-case-generator/index.html | 2 +- public/ai-debate-coach/index.html | 2 +- public/ai-debate-practice/index.html | 2 +- public/ai-rebuttal-generator/index.html | 2 +- .../ai-vs-traditional-debate-prep/index.html | 8 +-- public/argument-flowchart/index.html | 2 +- public/best-ai-debate-tools/index.html | 2 +- .../british-parliamentary-debate/index.html | 8 +-- public/congress-debate/index.html | 8 +-- public/debate-block-file-guide/index.html | 8 +-- public/debate-clash-points/index.html | 8 +-- public/debate-collapsing-strategy/index.html | 8 +-- public/debate-evidence-finder/index.html | 2 +- public/debate-fallacies/index.html | 8 +-- public/debate-judge-adaptation/index.html | 8 +-- public/debate-motion-analysis/index.html | 8 +-- public/debate-prep-time-management/index.html | 8 +-- .../index.html | 8 +-- public/debate-rebuttal-practice/index.html | 2 +- public/debate-speech-structure/index.html | 8 +-- public/debate-topics-for-students/index.html | 2 +- public/debatelab-pricing/index.html | 10 ++-- public/debatelab-vs-chatgpt/index.html | 2 +- public/debatelab-vs-debateclub/index.html | 8 +-- public/debatelab-vs-windebate/index.html | 8 +-- .../how-to-cross-examine-in-debate/index.html | 2 +- public/how-to-flow-in-debate/index.html | 2 +- public/how-to-practice-rebuttals/index.html | 2 +- .../index.html | 8 +-- public/how-to-weigh-in-debate/index.html | 2 +- public/how-to-write-a-debate-case/index.html | 2 +- public/lincoln-douglas-debate/index.html | 8 +-- public/llms.txt | 4 +- public/online-debate-timer/index.html | 2 +- public/policy-debate/index.html | 8 +-- public/public-forum-debate/index.html | 2 +- public/world-schools-debate/index.html | 2 +- scripts/check-site.mjs | 7 +++ scripts/generate_seo_content.py | 53 +++++++++++++++---- scripts/seo_answers.py | 8 +-- scripts/seo_guides.py | 36 +++++++------ src/components/features/tools/tool-links.tsx | 4 ++ src/components/landing/FAQ.tsx | 3 +- src/components/landing/Pricing.tsx | 7 ++- src/locales/en.json | 25 ++++----- src/locales/es.json | 25 ++++----- src/locales/hu.json | 25 ++++----- src/pages/PrivacyPage.tsx | 2 +- src/prerender/entry.tsx | 9 ++-- 51 files changed, 226 insertions(+), 172 deletions(-) diff --git a/docs/operations.md b/docs/operations.md index ec3a5dadf..16c958dc6 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -58,15 +58,15 @@ The free tools under `/tools` ([`src/pages/tools/`](../src/pages/tools/)) are pr [`scripts/sitemap.mjs`](../scripts/sitemap.mjs) then writes `dist/sitemap.xml` from every page in `dist/` that names itself as canonical and is not `noindex`. Each `` is the `dateModified` the page declares in its JSON-LD: the guide pages' `CONTENT_DATE` in [`scripts/generate_seo_content.py`](../scripts/generate_seo_content.py), the legal pages' "last updated" dates, the tool pages' `TOOL_PAGES_MODIFIED`, and the landing page's last source commit. A page without a date is listed without ``. -[`scripts/check-site.mjs`](../scripts/check-site.mjs) runs next and fails the build when an internal link, a `#fragment`, a sitemap URL or an `llms.txt` URL does not resolve (it applies the `vercel.json` redirects and rewrites), when JSON-LD does not parse or carries HTML entities, when an indexed page other than `/terms`, `/privacy`, and `/expocit/sources` lacks its question H2 (`#short-answer`) as the first H2, or when an image has no alt text, a button has no name or a form field has no label. +[`scripts/check-site.mjs`](../scripts/check-site.mjs) runs next and fails the build when an internal link, a `#fragment`, a sitemap URL or an `llms.txt` URL does not resolve (it applies the `vercel.json` redirects and rewrites), when JSON-LD does not parse or carries HTML entities, when an indexed page other than `/terms`, `/privacy`, and `/expocit/sources` lacks its question H2 (`#short-answer`) as the first H2, when a page's first heading is not its H1 or a heading skips a level (H1 to H3), or when an image has no alt text, a button has no name or a form field has no label. -The guide pages in `public//index.html` are generated, not hand-edited: run `python3 scripts/generate_seo_content.py` and commit its output. Short pages live in its `PAGES` list; pages with long-form copy, their own highlight-card descriptions, and their own FAQs (which also feed the page's FAQPage JSON-LD) live in [`scripts/seo_guides.py`](../scripts/seo_guides.py). Keep `PAGES` in order, because each page's related-guide links are picked by position. A guide entry can set its own `modified` date, which overrides `CONTENT_DATE` for that page alone. +The guide pages in `public//index.html` are generated, not hand-edited: run `python3 scripts/generate_seo_content.py` and commit its output. Short pages live in its `PAGES` list; pages with long-form copy, their own highlight-card descriptions, and their own FAQs (which also feed the page's FAQPage JSON-LD) live in [`scripts/seo_guides.py`](../scripts/seo_guides.py). Keep `PAGES` in order, because each page's related-guide links are picked by position. A guide entry can set its own `modified` date, which overrides `CONTENT_DATE` for that page alone. Pages that show the shared `FAQS` are dated no earlier than `FAQS_DATE`, so move it when those questions change. Every guide opens with the reader's main question as its first H2 and an answer of at most 100 words, kept in [`scripts/seo_answers.py`](../scripts/seo_answers.py); the generator refuses a page without one or with a longer answer. Each guide shows visible "Published" and "Updated" dates (`PUBLISHED_DATE` or a `published` key, and the `modified` date) that match its Article JSON-LD. Prices and plan facts are stated "as of" the month in `factsCheckedOn` in `src/config/site.json`; move that date when you recheck them, and the generated About line on every guide, `llms.txt` and the landing page follow. Copy in `seo_guides.py` and `seo_answers.py` that names the month itself (prices and competitor facts) needs the same edit: search those files for "As of". The generator also writes `public/llms.txt`, the plain summary for AI agents. `public/robots.txt` allows AI crawlers by name in their own group, which repeats the private-route rules because a crawler that matches a named group ignores `*`. To retire a guide, delete its `PAGES` entry and its `public//` folder (the generator never deletes), add its redirects to `vercel.json`, and repoint any link to it. Two guides that answer the same search should become one page, not two thin ones. -The site origin, product name, brand line, and organization name live in [`src/config/site.json`](../src/config/site.json). The app's head tags, the prerender and sitemap scripts, and the guide generator all read it, and guide copy names the product with a `{product}` token. Do not hardcode those strings in new code or copy. +The site origin, product name, brand line, and organization name live in [`src/config/site.json`](../src/config/site.json). The app's head tags, the prerender and sitemap scripts, and the guide generator all read it, and guide copy names the product with a `{product}` token and the Pro price with `{pro_price}`. The number of prep modes comes from the tool lists in [`tool-links.tsx`](../src/components/features/tools/tool-links.tsx): the app's copy reads `PREP_MODE_COUNT` and `UTILITY_COUNT`, and guide copy uses `{mode_count}`, `{mode_names}` and `{utility_names}`. Do not hardcode those strings in new code or copy. [`src/test/vercel-deployment-config.test.ts`](../src/test/vercel-deployment-config.test.ts) guards these rules. Update it together with `vercel.json`, and do not paste the full configuration into another guide. diff --git a/docs/testing.md b/docs/testing.md index d7835a81d..82053ebb7 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -102,7 +102,7 @@ This sends one tiny typed choice to OpenRouter's Decisions endpoint using the pi npm run build ``` -This proves the Vite production bundle compiles, prerenders the public pages, checks the built site's links, fragments, JSON-LD and basic accessibility with `scripts/check-site.mjs`, and then walks the emitted Vite manifest to reject feature-only PDF, DOCX, chart, ReactFlow, export, and Admin modules from the static `index.html` dependency graph. It does not prove authentication, database behavior, provider access, or production deployment. +This proves the Vite production bundle compiles, prerenders the public pages, checks the built site's links, fragments, JSON-LD and basic accessibility (including heading order) with `scripts/check-site.mjs`, and then walks the emitted Vite manifest to reject feature-only PDF, DOCX, chart, ReactFlow, export, and Admin modules from the static `index.html` dependency graph. It does not prove authentication, database behavior, provider access, or production deployment. ## Production service-worker smoke diff --git a/public/ai-debate-case-generator/index.html b/public/ai-debate-case-generator/index.html index 242298b8f..36025f782 100644 --- a/public/ai-debate-case-generator/index.html +++ b/public/ai-debate-case-generator/index.html @@ -22,7 +22,7 @@ - +
diff --git a/public/ai-debate-coach/index.html b/public/ai-debate-coach/index.html index 1bb6973ae..a3cdeea25 100644 --- a/public/ai-debate-coach/index.html +++ b/public/ai-debate-coach/index.html @@ -22,7 +22,7 @@ - +
diff --git a/public/ai-debate-practice/index.html b/public/ai-debate-practice/index.html index 4dcaf918f..fd244a00f 100644 --- a/public/ai-debate-practice/index.html +++ b/public/ai-debate-practice/index.html @@ -22,7 +22,7 @@ - +
diff --git a/public/ai-rebuttal-generator/index.html b/public/ai-rebuttal-generator/index.html index 26b135157..ea51f48d1 100644 --- a/public/ai-rebuttal-generator/index.html +++ b/public/ai-rebuttal-generator/index.html @@ -22,7 +22,7 @@ - +
diff --git a/public/ai-vs-traditional-debate-prep/index.html b/public/ai-vs-traditional-debate-prep/index.html index f5ffe1f3a..f967437bb 100644 --- a/public/ai-vs-traditional-debate-prep/index.html +++ b/public/ai-vs-traditional-debate-prep/index.html @@ -17,12 +17,12 @@ - + - +
@@ -31,11 +31,11 @@
-
Comparison

AI vs Traditional Debate Prep

AI speeds up structure; traditional research and coaching provide depth and judgment.

Published · Updated

+
Comparison

AI vs Traditional Debate Prep

AI speeds up structure; traditional research and coaching provide depth and judgment.

Published · Updated

Is AI debate prep better than traditional research and coaching?

Neither replaces the other. AI is faster at structure: case outlines, rebuttal blocks, topic brainstorming and evidence leads, which saves time on the repetitive parts of prep. Traditional prep does better at original source reading, real coaching feedback, tournament-specific strategy and adapting to a specific opponent, because those need human judgment. The practical answer is to combine them: use AI for scaffolding, traditional research for depth and coaching for strategy.

Speed and structure

Research depth

Human judgment

What AI does well

AI generates structure fast: case outlines, rebuttal blocks, topic brainstorming, and evidence leads. It saves time on the repetitive parts of prep.

What traditional prep does better

Original source reading, real coaching feedback, tournament-specific strategy, and adapting to a specific opponent all require human judgment.

How to combine them

Use AI for scaffolding, use traditional research for depth, and use coaching for strategy. DebateLab supports the AI scaffolding step.

-

Frequently asked questions

Is DebateLab an AI debate practice platform?

Yes. DebateLab focuses on debate prep workflows such as cases, rebuttals, evidence, flowcharts, coaching, and timing.

Can Google index private DebateLab app pages?

No. Private dashboards and account routes should remain noindexed while public guides provide crawlable context.

Should students verify AI-generated debate evidence?

Yes. AI can suggest research leads, but students should check original sources before using evidence in round.

+

Frequently asked questions

Is DebateLab an AI debate practice platform?

Yes. DebateLab focuses on debate prep workflows such as cases, rebuttals, evidence, flowcharts, coaching, and timing.

Should students verify AI-generated debate evidence?

Yes. AI can suggest research leads, but students should check original sources before using evidence in round.