Repository navigation
feat(demo): start-chat confirmation page, question after # (founder ruling 2026-10-03) - #186
Conversation
…uling 2026-10-03) The demo hand-off now goes to a page of its own, /project/github.com/<owner>/<repo>/start-chat#msg=<q>&lang=<en|ru> (and .../tree/<ref>[/<dir>]/-/start-chat#...), with the question in the fragment so it never reaches the server or a referrer. - index.html inline script: on a start-chat path takes msg/q/lang from the fragment (and the query, for no-JS form posts), stashes them exactly as the existing hand-off does, and replaceStates to the same path with the fragment and those query keys removed (other keys kept). /demo and the old .../chat?msg=... are handled as before. - demo-handoff-path: new start-chat target (with folder support); the route table decision (handoffDecision) replaces showsHoldingPage: /demo and start-chat are the page, the old chat address with a question is replaced by start-chat of the same project, without a question it is the ordinary chat page. /chat never reads a question. - demo-handoff-capture: start-chat reads and strips the live fragment/query itself as a backstop; trust is unchanged (a folder is never trusted). - Holding page: same component and strings; state is now a signal so a fragment pasted over the open page (no reload) is taken and removed too. A TODO(G-A4b) marks where "Start" goes once the chat can run a question. - Specs: path, decision, routes, capture and inline script, holding page; e2e against the production build covers the privacy matrix for fragment, query, old chat, /demo, // and root-group spellings, trusted and other projects. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
[review r1 #186] Adversarial review (Opus): production builds of this head and of main served side by side; 52 hand-off addresses plus the earlier review's 153; Back/Forward/reload, pasted fragment, 6 KB message, HTML payload; GA stand-in, Navigation API, PostHog and Sentry bodies recorded with positive controls; 3,125 unit tests; mutants of every start-chat branch. Reviewed-Head: 8a6238e No question leaks or is echoed where main protected it. Minors, carried to #184:
Not verified: PostHog event bodies (only VERDICT: blockers=0 majors=0 minors=4 land=yes 🤖 Generated with Claude Code |
What
Founder ruling 2026-10-03 (
backstagedocs/design/demo-as-github-project.md, "Founder ruling 2026-10-03", 3.1, 6.5): the demo hand-off goes to a confirmation page…/start-chatwith the question after#. The demo flag stays off; nothing here turns the demo on. Landing deploys to the live app, so please review before landing.All paths below are under
apps/datatug-app/.Required behaviour, where it is, and the test
…/start-chat#msg=&lang=and…/tree/<ref>[/<dir>]/-/start-chat#…;qis an alias ofmsg; URLSearchParams semanticssrc/app/demo-handoff-path.ts:36-139(targetstart-chat, folder support,startChatSegmentsOf); fragment parsingsrc/app/demo-handoff-capture.ts:92-145,src/index.html:62-80demo-handoff-path.spec.ts(targets, router agreement),demo-handoff-capture.spec.ts"the start-chat address: the question after #", "capture of the start-chat address"msg/q/langfrom the fragment and the query, stashes them as today,replaceStates to the same path with the fragment and those query keys removed (other keys kept); old addresses unchanged in effect; reuses #183's//and root-group normalisationsrc/index.html:36-100demo-handoff-capture.spec.ts("acts on exactly the paths isHandoffPath accepts" extended to the fragment; "agrees with the TypeScript on every spelling")isTrustedHandoff), neutral wording otherwise, same two actions; a reload shows the question from the tab's stash; seam for "Start"src/app/demo-holding-page.component.ts(readView,TODO(G-A4b)at :65),src/app/demo-handoff-asked.ts:183(handoffDecision: start-chat is always the page),src/app/demo-handoff-capture.ts:60-85(trust: a folder is never trusted)demo-holding-page.component.spec.ts"…on the start-chat address",demo-handoff-asked.spec.ts"the decision for an address",datatug-app-routes.spec.ts"start-chat"/chatnever reads a questionhandoffDecisionreturnsnonefor…/chatwithout a stashed question, and the page code reads no question from itdatatug-app-routes.spec.ts, e2e "the project chat page never reads a question"…/chat?msg=and?q=are replaced by…/start-chat(no question in the address);/demo?q=…&scenario=…&lang=…stays as today; the router safety net that removesmsg/qunder/project/github.com/is untouchedsrc/app/datatug-app-routes.ts:77-92(RedirectCommand,replaceUrl: true)datatug-app-routes.spec.ts(move, replaces history, keeps case of ref), e2e "the old chat address with a question is replaced by start-chat: Back does not return to it", "/demo?q=…&scenario=…&lang=… … still shows the holding page"e2e/demo-handoff.spec.ts"the start-chat confirmation page": for fragment, fragment withq, query, query with another key, old chat (msg,q),//and root-group spellings, each on the demo project and onacme/demo: address bar, every history entry (Navigation API),history.*calls, title, storage (only the existing per-tab hand-off key, trusted only), own and third-party requests carry no question; the trusted project echoes it,acme/demois neutral. Plus: a fragment question is in no request at all, not even the document request or a referrerChoices where the design was silent
…/start-chat(no fragment) shows the same holding page with nothing to confirm (the no-question sentence for the trusted project, neutral wording otherwise). It does not open the project chat: 6.5 row 2 says the holding page, and the chat of a GitHub project shows a data error until G-A7. Tested.TODO(G-A4b)in the component header says where it goes and that the flag is read wheredemo-flag.tsis read (the spec forbids importing it here).start-chatonly. The old…/chataddress keeps its shape (no folder), as today. A start-chat address in a folder or on a ref other thanHEADis a hand-off address and is never trusted.//project/…and/(project/…)spellings to the plain address on first navigation; the question is gone either way.#msg=on…/chator any other page is not a hand-off (no new special cases); it is neither read nor stripped there.…/chat?msg=is written by the script under the chat path and rewritten under the start-chat path by the page on first render (a reload in the few milliseconds between shows the page without the question).Checks
vitestapp project, 708 tests pass (14 files).pnpm run check:zonelessOK.nx lint datatug-apppasses, no findings.playwright.demo-handoff.config.tsagainst the production build: 113 passed (was 82; the 7 old-chat cases that asserted the address stays…/chatnow assert…/start-chat). The config's ownwebServercould not start underwb runin this worktree (the nestedpnpm nx serveexits 1 at once), so the production dev-server was started separately and reused.origin/maina248156 vs this branch:mainchunk 1,227,478 to 1,228,168 bytes raw (+690 B), 324,975 to 325,189 gzip (+214 B); nx "Initial total" 2.10 MB both, estimated transfer 470.90 kB to 470.94 kB.github-project-routes.ts,datatug-routing-*.Screenshots (390 and 1280; trusted en and ru with a question, bare, untrusted):
/private/tmp/claude-501/-Users-alex-projects/27bc30d5-3ff1-4e50-a5d9-9c67e328b1e3/scratchpad/apps-start-chat/shots/.🤖 Generated with Claude Code