Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,16 @@ bodies total 37,095 bytes. **This retires the Option C frozen-tail invariant by
existed only to police a boundary inside an unreviewable single line, and the append-only rule above
supersedes it. No bespoke hash is needed for future updates: the diff is the proof.

### 2026-10-07 - Store path step a live and proven on production: the app marker gets the prerendered twins without the Google button or the Pricing link, the web gets its cached pages untouched, a web request right after an app request is a cache HIT of the web variant, and the eleven public pages are byte-identical for visitors

**No row is edited. Outside this file: nothing in the repository; on production, the deploy of `bfd8c7b` (PR #239 merged by the owner's pinned line, Vercel success, Railway success). Rows 42, 69 and 81 are not touched, and Section 7 takes no deletions.**

**THE READ, 2026-10-07 after the deploy (`curl`, read-only; an iPhone Safari user agent for the web, the same with `KnowFlowApp/1` appended for the app).** **The web variant:** `/en/login`, `/ar/login`, `/en/signup`, `/ar/signup` answer 200 with the Google button (`fill="#4285F4"` once each), `/en/privacy`, `/ar/privacy` and `/en` with two Pricing links, `/en/pricing` with its four and its Upgrade; every one `X-Nextjs-Prerender: 1`, `X-Vercel-Cache: HIT` or `PRERENDER`, `Cache-Control: public, max-age=0, must-revalidate`: the pages as they were, from the CDN. **The app variant:** the same six pages answer 200 with **no Google button and no Pricing link, in both locales**, also `X-Nextjs-Prerender: 1` and served from the cache (`PRERENDER` on first read, `HIT` on the second and third): the twin, prerendered at its own key; `/en` and `/en/pricing` answer **307 to `/en/dashboard`**. **No bleed:** a web request for `/en/login`, `/ar/login` and `/en/privacy` made immediately after the app request for the same URL answers the web variant (Google button and Pricing links present) as a cache `HIT`. **A web visit straight to `/en/native/login` answers 404** (`private, no-store`, the 404 page); the app's visit to it answers 200 from the cache. **Router prefetch:** `GET /en/login?_rsc=…` with `RSC: 1` and `Next-Router-Prefetch: 1` answers `text/x-component` for both; the web payload carries no platform prop, the app's carries `"platform":"native"` once, the provider of the twin's layout. **The API path:** `/api/check-limit` answers 401 to both, unauthenticated, as it must. **TTFB after, for the web:** `/en` 0.17 s, `/en/login` 0.19 s, `/en/privacy` 0.19 s, against 0.18–0.20 s before: unchanged, as the design promised.

**WEB VISITORS SEE WHAT THEY SAW.** The eleven public pages captured from production before the change (`/`, `/login`, `/signup`, `/pricing` in both locales; `/about`, `/privacy`, `/forgot-password` in English) were fetched again after the deploy and compared with scripts, build-hashed asset paths and React's per-build comment markers removed: **all eleven identical**, once React's generated element ids (`_R_…_`, the `for`/`id` pairs of the form fields, which shift because the `[locale]` layout no longer renders the deleted `NativePlatformHeader` client component ahead of them) are masked; the pairs still match, and nothing a visitor sees or a crawler reads changed.

**WHAT CLOSES AND WHAT DOES NOT.** Step a of `docs/store/STORE_PATH.md` is done: the marker is read per request, only removes, is gated in CI, and both variants are proven on production with no cache bleed. Step b is the Capacitor config and the native projects, exactly as the previous block fixed it. The one reading only the phone can take, client-side navigation inside the app between two rewritten pages and from a twin to the dashboard, is T5's first check.

### 2026-10-07 - Store path step a built: the request-time platform marker; inside the app no purchase, upgrade or pricing surface and no Google button, read per request from `KnowFlowApp/<n>` in the user agent; the web's pages stay on the CDN and the app is rewritten to prerendered twins; gated in CI by `verify-platform-gate.mjs`

**No row is edited. Outside this file: `src/lib/platform.ts` (rewritten: `platformFromHeaders`, `purchaseLinksAllowed(platform)`, `googleSignInAllowed(platform)`, the build-time `PLATFORM` and `NEXT_PUBLIC_KF_PLATFORM` gone), `src/lib/platform-server.ts` (new, `currentPlatform()` over `headers()`, for the signed-in pages only), `src/components/platform/PlatformProvider.tsx` (new, context for client components), `src/components/platform/NativePlatformHeader.tsx` (deleted), `src/components/layout/SiteChrome.tsx` (new, the public site's chrome taken out of `(site)/layout.tsx` so two layouts can render it), `src/app/[locale]/native/` (new: `layout.tsx` with `robots: noindex` and `PlatformProvider platform="native"`, `(site)/layout.tsx` rendering the chrome without the Pricing link, and seven pages that are bare re-exports of `login`, `signup`, `about`, `contact`, `privacy`, `terms`, `refund`), `src/middleware.ts` (an app request for `/<locale>` or `/<locale>/pricing` → 307 to the dashboard; for the seven pages above → rewrite to the twin; a web visit to a `/native/` path → the 404 page), `src/components/layout/SiteHeader.tsx` (`showPricing`), `src/app/[locale]/dashboard/layout.tsx`, `dashboard/page.tsx`, `dashboard/settings/page.tsx`, `dashboard/knowledge/new/page.tsx`, `src/lib/home-props.ts` (`buildHrefs(locale, platform)`, `appHrefs`), `src/components/auth/GoogleButton.tsx` (returns nothing inside the app), `src/app/[locale]/preview/student-home/page.tsx` (`?platform=native`), `scripts/verify-platform-gate.mjs` (new) as a step of the required `tsc` job, `scripts/verify-store-purchase-links.mjs` (the user-agent reading added), and `docs/store/STORE_PATH.md` (T1 done, T2's exact scope, corrections). No schema, grant, auth config, template or env change. Rows 42, 69 and 81 are not touched, and Section 7 takes no deletions.**
Expand Down
Loading