-
Notifications
You must be signed in to change notification settings - Fork 0
feat(privacy): Quiet Signal production page with elevated processing map #1833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
a288601
feat(privacy): adopt Quiet Signal layout on /privacy
cursoragent 0f37160
polish(privacy): tighten Quiet Signal Important chrome
cursoragent 33bef1c
Merge branch 'main' into cursor/privacy-quiet-signal-adopt-bc81
BigSimmo 91844e0
fix(privacy): align Quiet Signal page with mockup chrome
cursoragent cce6859
Merge branch 'main' into cursor/privacy-quiet-signal-adopt-bc81
BigSimmo e4dcae2
fix(privacy): repair processing map across breakpoints
cursoragent fcf5e62
Merge branch 'main' into cursor/privacy-quiet-signal-adopt-bc81
BigSimmo 9d4a8c8
Merge origin/main into cursor/privacy-quiet-signal-adopt-bc81
cursoragent 6817578
fix(privacy): clear Quiet Signal CI and review blockers
cursoragent 8ff4241
feat(privacy): elevate processing map as sticky instrument
cursoragent File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,128 +1,17 @@ | ||
| import type { Metadata } from "next"; | ||
| import { Suspense, type ReactNode } from "react"; | ||
|
|
||
| import { ClinicalBadge } from "@/components/clinical-dashboard/clinical-badge"; | ||
| import { NavigationBackButton } from "@/components/navigation-back-button"; | ||
| import { PrivacyPageBackButton } from "@/components/privacy-page-back-button"; | ||
| import { | ||
| cn, | ||
| eyebrowText, | ||
| raisedCard, | ||
| searchPageCanvas, | ||
| searchPageContainer, | ||
| searchPageShellStandalone, | ||
| } from "@/components/ui-primitives"; | ||
| import { privacyCopy } from "@/lib/ui-copy"; | ||
| import { PrivacyQuietSignalPage } from "@/components/privacy-quiet-signal-page"; | ||
|
|
||
| export const metadata: Metadata = { | ||
| title: "Privacy & data handling — Clinical KB", | ||
| description: "Draft product information about how Clinical KB handles questions and documents.", | ||
| }; | ||
|
|
||
| type Section = { heading: string; body: ReactNode }; | ||
|
|
||
| const SECTIONS: Section[] = [ | ||
| { | ||
| heading: "What this tool is", | ||
| body: ( | ||
| <> | ||
| Clinical KB is a knowledge base over clinical reference material. It is{" "} | ||
| <strong>not a patient-record system</strong> and its provider-backed features do not ask for patient | ||
| identifiers. The Safety Plan Generator accepts sensitive working content and support contacts but deliberately | ||
| omits a patient-identifier field. | ||
| </> | ||
| ), | ||
| }, | ||
| { | ||
| heading: "What is collected", | ||
| body: "Questions, generated answers, account identifiers, uploaded documents, retrieved excerpts, document metadata, and operational or retrieval telemetry may be processed. Free text and uploaded material can contain sensitive information if you enter it. Safety-plan working content is different: it remains in the current browser tab and is not sent to the application service or stored by Clinical KB.", | ||
| }, | ||
| { | ||
| heading: "How questions are handled", | ||
| body: ( | ||
| <> | ||
| Raw question text is not written to query logs by default; logs use a keyed one-way hash. Generated answer text | ||
| is also omitted from durable query logs by default. A short-lived response cache can contain the answer while | ||
| its read TTL is valid. To make recent answers reappear quickly, completed answer threads may also remain in this | ||
| browser tab for up to 12 hours. That tab-only copy stays in this tab, is not shared across tabs or devices, and | ||
| is never sent to the application service. | ||
| </> | ||
| ), | ||
| }, | ||
| { | ||
| heading: "Where data is stored and processed", | ||
| body: "Documents, extracted evidence, metadata, account records, and owner-scoped operational records are stored in the configured Supabase project in Sydney. The production application and ingestion worker currently run on Railway in Singapore, so questions, retrieved evidence, answers, and ingestion material are processed in or transit through Singapore. File buckets are private and links are time-limited. The operator must verify deployed regions and contractual controls.", | ||
| }, | ||
| { | ||
| heading: "External provider processing", | ||
| body: ( | ||
| <> | ||
| When external provider mode is configured, question text may be sent to the OpenAI API to create a retrieval | ||
| embedding, including when the final response is source-only. When model-backed answer synthesis is used, the | ||
| question and selected source excerpts are also sent. This processing may occur outside Australia. The operator | ||
| must verify provider regions, retention terms, contracts, and cross-border obligations. | ||
| </> | ||
| ), | ||
| }, | ||
| { | ||
| heading: "Retention", | ||
| body: "Repository migrations configure 30-day retention for RAG query records, 90-day retention for retrieval logs and query-miss telemetry, and a bounded hourly purge of expired response-cache rows when the database scheduler is available. The operator must verify that those scheduled jobs are active. Uploaded documents remain until removed under the applicable process. Completed answer threads in the current browser tab expire no later than 12 hours after the most recent answer and are also cleared by New chat, sign-out, or an account change. Safety-plan working content has no Clinical KB retention: it is discarded when the component is cleared or the tab is closed. Clipboard, print, and PDF copies are outside the app and must follow the organisation's approved record-handling process.", | ||
| }, | ||
| { | ||
| heading: "Your responsibilities", | ||
| body: "Do not enter patient-identifiable information. In the Safety Plan Generator, add any patient identifier only after export through your organisation's approved clinical-record process. Upload only material you are authorised to use, keep access credentials private, review original linked sources before relying on clinical output, and report suspected privacy or access issues through your organisation's approved process.", | ||
| }, | ||
| ]; | ||
|
|
||
| /** | ||
| * Quiet Signal privacy page: sticky Important, processing map, accordion with | ||
| * gists, desktop Signal Index — no phone number-chip strip. Governance wording | ||
| * lives in `src/lib/privacy-page-content.tsx` (pinned by `tests/privacy-ui.test.ts`). | ||
| */ | ||
| export default function PrivacyPage() { | ||
| return ( | ||
| <main className={cn(searchPageCanvas)}> | ||
| {/* | ||
| Privacy sits outside the search shell, so this page owns the OS top inset | ||
| via searchPageShellStandalone (max(safe-area-top) baked into the pad). | ||
| */} | ||
| <div className={cn(searchPageShellStandalone)}> | ||
| <div className={cn(searchPageContainer, "space-y-6")}> | ||
| <header className="space-y-4"> | ||
| <div className="flex min-h-tap items-center"> | ||
| <Suspense fallback={<NavigationBackButton fallbackHref="/" />}> | ||
| <PrivacyPageBackButton /> | ||
| </Suspense> | ||
| </div> | ||
| <div className="space-y-2"> | ||
| <p className={eyebrowText}>{privacyCopy.pageEyebrow}</p> | ||
| <h1 className="text-2xl font-semibold tracking-tight text-[color:var(--text-heading)] sm:text-3xl"> | ||
| {privacyCopy.pageTitle} | ||
| </h1> | ||
| <p className="max-w-[68ch] text-sm leading-6 text-[color:var(--text-muted)]"> | ||
| This is draft product information based on the repository's configured behaviour. It is not legal | ||
| advice, a final privacy policy, or an assertion of governance approval. | ||
| </p> | ||
| </div> | ||
| </header> | ||
|
|
||
| <section className={cn(raisedCard, "p-4 sm:p-5")}> | ||
| <div className="flex items-start gap-3"> | ||
| <div className="shrink-0 pt-0.5"> | ||
| <ClinicalBadge tone="warning" label="Important" /> | ||
| </div> | ||
| <p className="min-w-0 text-sm leading-6 text-[color:var(--text-heading)]"> | ||
| Do not enter identifiable patient details such as names, dates of birth, or record numbers. Requests are | ||
| processed by the application service in Singapore. With external provider mode configured, question text | ||
| may be sent to the OpenAI API for retrieval embedding even when the final response is source-only; | ||
| model-backed answer synthesis also sends the question and selected evidence. | ||
| </p> | ||
| </div> | ||
| </section> | ||
|
|
||
| {SECTIONS.map((section) => ( | ||
| <section key={section.heading} className={cn(raisedCard, "p-4 sm:p-5")}> | ||
| <h2 className="text-base font-semibold text-[color:var(--text-heading)]">{section.heading}</h2> | ||
| <p className="mt-1.5 max-w-[68ch] text-sm leading-6 text-[color:var(--text-muted)]">{section.body}</p> | ||
| </section> | ||
| ))} | ||
| </div> | ||
| </div> | ||
| </main> | ||
| ); | ||
| return <PrivacyQuietSignalPage />; | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.