Skip to content

feat(store): step a, the request-time platform marker; inside the app no purchase, upgrade or pricing surface and no Google button; gated pages render per request; CI gate verify-platform-gate.mjs - #239

Merged
tornidomaroc-web merged 2 commits into
mainfrom
feat/store-a-platform-marker
Oct 7, 2026

Conversation

@tornidomaroc-web

@tornidomaroc-web tornidomaroc-web commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

docs/store/STORE_PATH.md step a: the server-side half of the request-time platform marker, and everything that reads it. Step b (the Capacitor config that sends it) only has to set appendUserAgent: 'KnowFlowApp/1'.

Rebuilt on the owner's objection (second commit). The first build made the landing, the marketing and legal pages, login and signup render per request for every visitor. Measured on production (five samples each): a CDN-served page answers in 0.18–0.20 s, a function-rendered response in 0.26–0.31 s warm and about 1.0 s cold, and every visit would have been a function invocation against the Hobby allowance (1M invocations, 4 CPU-hours, 360 GB-hours a month; no overage billing, Vercel pauses). The design now:

  • The web is untouched. Every public page stays prerendered and on the CDN. .next/prerender-manifest.json after the build lists /en/login, /en/signup, /en, /en/privacy and the Arabic ones as before.
  • The app gets twins. Each page a signed-out student can meet has a prerendered twin under /<locale>/native/ (seven bare re-exports under a layout that hides the Pricing link and the Google button). The middleware, which already runs on every request, rewrites an app request to the twin; the URL stays; each variant sits at its own cache key, so no Vary is needed and no bleed is possible. Vercel: Routing Middleware "runs globally before the cache"; Next: NextResponse.rewrite() "automatically propagates the required RSC rewrite headers upstream", so router prefetches land on the twin too. The user agent survives the header stripping of fix(#136): only a page load writes kf-locale; every link that crosses languages is a plain <a> #226/fix(#136): the guard reads what the middleware receives: Sec-Fetch-Dest, else Accept #227.
  • Signed-in pages are rendered per request already and read the marker through currentPlatform().
  • The landing and /pricing redirect to the dashboard for the app; a web visit straight to a /native/ path gets the 404 page.

The five requirements

  1. Only removes. Two predicates, one redirect and one rewrite consume the reading; each takes something away. The proof renders every gated surface both ways and asserts every native href is also a web href; a forged marker in a browser behaves exactly like the app.
  2. Caching. Above. The production reading after deploy (both variants, cache headers, a web request right after an app request, a direct twin visit, router prefetches, TTFB) is the next step.
  3. Every surface, listed first. Eight surfaces from grep over src/, each covered (Section 7 block).
  4. Web unchanged. Baseline HTML of eleven public pages captured from production before the change; the comparison after deploy is the next step.
  5. CI. scripts/verify-platform-gate.mjs in the required tsc job: renders, the real middleware (redirects, rewrites, the 404), and a source scan that fails on an ungated /pricing reference, upgradeHref or Google start, a predicate fed a literal or nothing, navigator.userAgent in client code, a static page or twin that reads the request, a twin that is not a bare re-export, or a twin missing from the middleware's list. Red on five deliberate breaks; green now. The other 19 proof steps pass locally.

Objections recorded

STORE_PATH.md said /refund would be sent to the app entry; it is a policy page, not a call to action, and is rewritten like the other legal pages. The file is corrected and T2's scope written down exactly.

Section 7: one block, additions only (0 deletions). Rows 42, 69, 81 untouched. No schema, grant, auth config, template or env change.

🤖 Generated with Claude Code

… no purchase, upgrade or pricing surface and no Google button, read per request from KnowFlowApp/<n>; the pages that change on it render per request; gated in CI by verify-platform-gate.mjs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
knowflow Ready Ready Preview Oct 7, 2026 10:15am UTC

@fixor-security

fixor-security Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

🛡️ Fixor Security Report

Repository: tornidomaroc-web/knowflow · PR: #239
Commit: 13580735fb8ca7295b5d54f3764b8f24b489ea23

⏸️ Fixor scan paused - budget reached

This installation has hit its $0.00 monthly cap (spent $0.00 this month).
This installation's cap is $0, so scans stay paused until the cap is raised.
To raise the cap, contact the Fixor operator. The current cap is shown on your dashboard's billing page.

🔒 Analyzed by Fixor · 2026-10-07T10:14:38.124Z

… stay prerendered on the CDN; the app is rewritten by the middleware to prerendered twins under /<locale>/native/ without the Pricing link and the Google button; measurements and the gate's new rules recorded

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@tornidomaroc-web
tornidomaroc-web merged commit bfd8c7b into main Oct 7, 2026
8 checks passed
@tornidomaroc-web
tornidomaroc-web deleted the feat/store-a-platform-marker branch October 7, 2026 11:05

This branch was successfully deployed

1 active deployment
Preview — 13580735 Deployed Oct 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant