diff --git a/CHANGELOG.md b/CHANGELOG.md index a47fd7f..9e8d2d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,9 +47,13 @@ CalVer image tags (`stable-YYYY.MM.N`, `dev-YYYY.MM.N`) are produced for every C stays local, `/agnes-private` toggles per-session) and the workspace-layout convention (*"Get the most out of it"* — work under `~//Projects/`, anything outside the - workspace root is invisible to the platform). Renders for both - onboarded and not-onboarded users so the operating model is - visible on every visit. + workspace root is invisible to the platform). Gated on the same + `instance.overview` / `AGNES_INSTANCE_OVERVIEW` flag that used + to drive the standalone Overview section — any non-empty value + acts as the feature flag — so the OSS keeps a vendor-neutral + default (empty yaml → footnotes absent) while operators who + flip the flag get a consistent message across instances. + Renders for both onboarded and not-onboarded users. - Welcome hero's *"AI Chief of Staff"* lede gains a trailing sentence ("*You run all your projects inside and it learns from it.*") so the workspace-folder framing lands before the @@ -259,11 +263,13 @@ CalVer image tags (`stable-YYYY.MM.N`, `dev-YYYY.MM.N`) are produced for every C `instance.overview` / `AGNES_INSTANCE_OVERVIEW` HTML body between the first-session walkthrough and the surfaces grid). The privacy-posture / workspace-layout copy it carried now ships - inline in the welcome hero footnotes, so a separate operator - surface for the same content is no longer needed. The - `get_instance_overview()` helper and yaml field remain (harmless - if set; just not rendered) so existing instances that override - it don't trip on a removed config key. + inline in the welcome hero footnotes (see *Changed* above). The + `get_instance_overview()` helper and yaml field still drive the + feature flag for the new footnotes block, but the raw HTML body + the operator stored there is no longer rendered (the static + product framing replaces it) — operators who relied on injecting + custom Overview HTML should migrate that content to + `instance.custom_scripts` or admin-edited news. ### Removed diff --git a/app/web/templates/home_not_onboarded.html b/app/web/templates/home_not_onboarded.html index 858cf50..00591cb 100644 --- a/app/web/templates/home_not_onboarded.html +++ b/app/web/templates/home_not_onboarded.html @@ -2289,6 +2289,25 @@

Shared analyst knowledge and prior solutions, fed back into Claude's context on demand.

+ {# Welcome-hero footnotes — operator-owned, opt-in. Gated on + the same `instance.overview` yaml field + (`AGNES_INSTANCE_OVERVIEW` env override) that used to + drive the standalone Overview section: any non-empty + value acts as the feature flag. The body itself is no + longer the operator's raw HTML — it's the canonical + product framing (privacy posture + workspace convention) + baked into the template, so the OSS keeps a + vendor-neutral default (empty yaml → footnotes absent) + while operators who flip the flag get a consistent + message across instances. #} + {# Footnotes are operator-owned reference content, not + per-user chrome — no dismiss button on purpose. A + one-time per-device hide would leave returning users + unable to re-read the privacy posture / workspace + convention without clearing localStorage. The whole + block is opt-in at the operator level (empty yaml → + block absent), which is the right axis of control. #} + {% if config.INSTANCE_OVERVIEW %}

What leaves your machine. Session telemetry — prompts, tool calls, @@ -2306,6 +2325,7 @@ Anything outside ~/{{ workspace_dir }}/ is invisible to the platform.

+ {% endif %} {# Homepage status frame — five counters with 24h/7d toggle. diff --git a/tests/test_web_home_page.py b/tests/test_web_home_page.py index 7b37d1b..a64f532 100644 --- a/tests/test_web_home_page.py +++ b/tests/test_web_home_page.py @@ -359,13 +359,17 @@ def test_setup_section_renders_for_not_onboarded(fresh_db): assert '
` was removed from - `/home` — its privacy / workspace-layout copy now ships inline - in the welcome hero footnotes. The `get_instance_overview()` - helper and `instance.overview` yaml field still exist (to avoid - breaking instances that override them), but the rendered - section MUST NOT appear regardless of the env value.""" +def test_overview_section_replaced_by_welcome_footnotes(fresh_db, monkeypatch): + """The standalone operator-owned Overview `
` was removed + from `/home`. Its privacy / workspace-layout copy now ships as + static product framing inside the welcome hero footnotes + (`.home-hero-footnotes`). The `instance.overview` yaml field + (`AGNES_INSTANCE_OVERVIEW`) keeps its gating role — any + non-empty value acts as the feature flag — but its raw HTML + body is no longer rendered (the static copy replaces it). When + set: the standalone section MUST stay absent and the + footnotes block MUST appear, but the raw yaml HTML body MUST + NOT leak into the page.""" monkeypatch.setenv("AGNES_INSTANCE_OVERVIEW", "

OVERVIEW_TEST_MARKER

") from src.db import get_system_db, close_system_db @@ -378,3 +382,31 @@ def test_overview_section_never_renders(fresh_db, monkeypatch): body = _client().get("/home", cookies={"access_token": sess}).text assert '
' not in body assert "OVERVIEW_TEST_MARKER" not in body + assert '
' in body + # "Get the most out of it" is unique to the footnotes block — the + # original "What leaves your machine" copy still exists in the + # session-privacy annotation lower on the page (untouched), so we + # can't use it as a footnotes marker. + assert "Get the most out of it" in body + + +def test_welcome_footnotes_hidden_when_overview_unset(fresh_db, monkeypatch): + """Default empty `instance.overview` (no env override) hides the + welcome-hero footnotes entirely so the OSS ships without the + central-catalog privacy framing baked into the welcome card.""" + monkeypatch.delenv("AGNES_INSTANCE_OVERVIEW", raising=False) + from src.db import get_system_db, close_system_db + + conn = get_system_db() + try: + _, sess = _make_user_and_session(conn) + finally: + conn.close() + close_system_db() + body = _client().get("/home", cookies={"access_token": sess}).text + assert '
' not in body + # "Get the most out of it" is the unique footnotes marker — the + # original "What leaves your machine" copy in the session-privacy + # annotation lower on the page always renders, so checking that + # would be a false-positive. + assert "Get the most out of it" not in body