From 8d2b4530459feb4450b32eaf85c8fca3cc3d2235 Mon Sep 17 00:00:00 2001 From: Timothy Oluwatobi Ojebiyi Date: Sat, 17 Oct 2026 01:04:46 +0100 Subject: [PATCH] fix(frontend): say where private details go instead of claiming the AI never sees them The Persona page said contact details, date of birth, salary and equality data "stay out of every prompt". That holds for the AI that writes CVs, letters and answers, but not for the form-filling agent, which is also an LLM: it gets name, contact details and date of birth in its task, and salary or equality answers when a form asks. The panel ("Where your private details go"), the Identity, salary and equality notes, and the README's privacy table now say so. The job-site password still reaches no model. --- README.md | 3 ++- frontend/src/app/profile/page.tsx | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3cd7aa4..a2b9102 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,8 @@ Labels: **High ≥ 65 %**, **Medium 35–65 %**, **Low < 35 %**. **Job fit** (`s | Required `JWT_SECRET` (no default) | `auth.py` | | Job-site password encrypted at rest, never returned to the browser | `crypto.py`, `tracker.py`, `main.py` | | Job-site password only typed into the job site's own fields, masked in prompts and logs; browser-use telemetry off | `browser_agent.py` | -| Persona sent to LLMs is an allowlist — no credentials, DOB, contact details, diversity data or salary | `agent._llm_persona` | +| Persona sent to the writing, scoring and question-reading LLM calls is an allowlist — no credentials, DOB, contact details, diversity data or salary | `agent._llm_persona`, `answers.py` | +| The form-filling agent (also an LLM) is given what forms ask for: name, contact details and DOB in its task, salary and equality answers only when a question asks; never the job-site password | `browser_agent.py` | | Server-side fetches of user-influenced URLs only reach public IPs, re-checked on every redirect | `net_guard.py` | | Shared job descriptions can only be refreshed from the stored job's own URL | `main._ensure_full_description` | | Application updates scoped to the owning user | `tracker.update_status` | diff --git a/frontend/src/app/profile/page.tsx b/frontend/src/app/profile/page.tsx index d976f68..2c76a73 100644 --- a/frontend/src/app/profile/page.tsx +++ b/frontend/src/app/profile/page.tsx @@ -281,7 +281,7 @@ export default function ProfilePage() { switch (section) { case "identity": return ( - +
set("core_info", "first_name", v)} autoComplete="given-name" /> set("core_info", "preferred_name", v)} /> @@ -521,7 +521,7 @@ export default function ProfilePage() { set("screening", "conflict_resolution", v)} />
set("screening", "salary_canonical", v)} - hint="Typed into salary fields. It never goes into AI prompts." /> + hint="Given only to the agent filling in a salary question, never used for writing." /> set("screening", "notice_period_canonical", v)} />
@@ -559,7 +559,7 @@ export default function ProfilePage() { ); case "equality": return ( - +
set("diversity", "gender", v)} /> set("diversity", "ethnicity", v)} /> @@ -647,10 +647,12 @@ export default function ProfilePage() { -

What the AI never sees

+

Where your private details go

- Contact details, date of birth, salary and equality data stay out of every prompt. Your job-board password is - encrypted and only ever typed into the job site itself. + The AI that writes your CVs, cover letters and answers never sees your contact details, date of birth, salary or + equality data. The agent that fills in forms is an AI too: it's given your name, contact details and date of + birth to type in, and your salary or equality answers when a form asks for them. Your job-board password reaches + no AI: it's encrypted, and only ever typed into the job site itself.