From ea1d919afb4d0aa8031a3d521d8219317f27f5c1 Mon Sep 17 00:00:00 2001 From: Raul Amedey Ciria Date: Mon, 2 Nov 2026 10:53:02 +0100 Subject: [PATCH] fix(privacy): align PII scrub copy with Presidio state and expose Solo audit log - Branch the 'Scrub personal details before training' description in personalize.html on presidio_available() so base installs without the privacy pack state that emails, phone numbers, and IDs are removed while names and places require the privacy pack (#155). - Pass presidio_available() and scrub_coverage() in personalize_get() and settings_post(), and drop the duplicated trailing caveat in settings.html (#155). - Link /audit from the Solo dashboard 'Your workspace' card and the Settings -> Privacy tab, and append UTC to event timestamps in audit.html (#156). Closes #155 Closes #156 Spec: docs/specs/privacy-pack-and-scrub-transparency.md Agent: Antigravity (automated, instructed-by: ramedey) Signed-off-by: Raul Amedey Ciria --- anthill/web/app.py | 9 +++++ anthill/web/templates/audit.html | 2 +- anthill/web/templates/dashboard.html | 3 +- anthill/web/templates/personalize.html | 4 +-- anthill/web/templates/settings.html | 4 +-- changelog.d/155.fixed.md | 1 + changelog.d/156.fixed.md | 1 + .../privacy-pack-and-scrub-transparency.md | 22 +++++++----- tests/test_privacy_pack_web.py | 35 ++++++++++++++++++- 9 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 changelog.d/155.fixed.md create mode 100644 changelog.d/156.fixed.md diff --git a/anthill/web/app.py b/anthill/web/app.py index 1e59462..9466b5b 100644 --- a/anthill/web/app.py +++ b/anthill/web/app.py @@ -6146,6 +6146,7 @@ def personalize_get(request: Request, user: dict = Depends(_require_user)): org = _require_org(db, user) me = db.query(User).filter(User.id == int(user["sub"])).first() from .. import planes + from ..hybrid.scrub import presidio_available from ..training.model_select import is_local_training, is_solo_account cfg = _cfg(db, org) @@ -6284,6 +6285,7 @@ def personalize_get(request: Request, user: dict = Depends(_require_user)): "web_access_on": bool(getattr(me, "web_access_on", False)) if me else False, "thinking_on": bool(getattr(me, "thinking_on", False)) if me else False, "scrub_on": bool(getattr(cfg, "cloud_scrub_pii", True)) if cfg else True, + "presidio_available": presidio_available(), "wiki_count": wiki_count, "model_storage_gb": model_storage_gb, "integrations_connected": integrations_connected, @@ -9003,6 +9005,9 @@ async def settings_post( user_id=user["sub"], ) audit.log(db, "settings.updated", "", org_id=org.id, user_id=user["sub"]) + from ..hybrid import privacy_pack as pack + from ..hybrid.scrub import presidio_available, scrub_coverage + return templates.TemplateResponse( request, "settings.html", @@ -9012,6 +9017,10 @@ async def settings_post( "org": org, "cfg": cfg, "saved": True, + "scrub_coverage": scrub_coverage(), + "presidio_available": presidio_available(), + "privacy_pack_can_install": pack.can_install(), + "privacy_installing": _privacy_pack_installing, }, ) diff --git a/anthill/web/templates/audit.html b/anthill/web/templates/audit.html index 1749b04..247df15 100644 --- a/anthill/web/templates/audit.html +++ b/anthill/web/templates/audit.html @@ -64,7 +64,7 @@

Recent events (last 200)

{% for e in events %} - {{ e.created_at.strftime('%m-%d %H:%M:%S') if e.created_at else '-' }} + {{ e.created_at.strftime('%m-%d %H:%M:%S UTC') if e.created_at else '-' }}