fix(web): history tab copy — every chat saves automatically, there is no Save button
Build and Push Containers / build-and-push-app (push) Successful in 1m35s
Build and Push Containers / build-and-push-db (push) Successful in 10s

meta description -> locked (A3) auto-save string (history.html L6).
page-sub -> locked (A3) string, the <strong>Save</strong> emphasis retired with the button (L106-109).
empty row -> locked (A3) string; colspan=6, hidden, and row id untouched (L163).
h1, the anonymous gate section, and history.js are byte-identical — state language verified accurate.
This commit is contained in:
2026-09-02 01:29:42 -04:00
parent 8a1f99cb38
commit f04ddbe1f8
16 changed files with 461 additions and 6 deletions
@@ -0,0 +1,30 @@
# Task 01 — Rewrite the History-tab copy to the auto-save model
**Phase:** `66_history_auto_save_copy` · **Source:** `TODO.md:4` — "Update the history tab - the text still reads like there's a save button. There isn't anymore, every chat is saved."
**Story:** n/a (TODO-derived)
## Objective
The three offending strings in `frontend/history.html` describe how BOR used to work (a Save button the visitor pressed). They become the locked (A3) auto-save copy — accurate, same house voice, no new markup.
## Work
1. `frontend/history.html` — three exact replacements (markup otherwise byte-identical):
- L6 — the meta description content becomes exactly (A3):
`Saved chats — every conversation is saved automatically, one click back.`
- L106–109 — the `.page-sub` becomes exactly (A3) — the `<strong>Save</strong>` emphasis is retired with the button; keep the `<p class="page-sub">` element, the indentation, and the single paragraph:
`Every conversation is saved automatically — newest activity first. Click a title to return to that chat.`
- L163 — the `#history-empty-row` cell text becomes exactly (A3):
`No saved chats yet — start a conversation and it will be saved automatically.`
(the `colspan="6"`, the `hidden` attribute, and the row's id are untouched — `history.js` reveals this exact row on a 0-row fetch).
2. Leave UNTOUCHED (verified accurate — "saved" as a state, not a button): the `<h1>Saved chats</h1>` (L105), the anonymous gate copy (L123–128), the table caption, every other row/cell in `history.html`, and everything in `frontend/assets/history.js` (its "saved chat" aria-labels are state language).
3. No CSS, no JS, no other page — the TODO scopes this to the history tab; any OTHER page found to name a Save button is noted in the commit body as follow-up material, not fixed here.
## Testing & Quality
- `uv run pytest` green (unit + integration — no Python changed); `uv run ruff check . && uv run pyright` clean.
- Coverage TOTAL **>90%** (validate.sh gate — unchanged, no `app/` code).
- Quick manual sanity (optional, before the pins land in task 02): `grep -n "Save" frontend/history.html` — the only remaining case-sensitive "Save" hits are the retired-comment-free state strings ("Saved chats" h1, "Saved conversations are admin-only", "saved chats" table aria-label/caption).
## Completion Criteria
- [ ] `grep -c "pressed <strong>Save</strong>\|press <strong>Save</strong>\|every conversation you saved" frontend/history.html` → 0.
- [ ] The three locked (A3) strings are present in `frontend/history.html` (meta, page-sub, empty row), each exactly once.
- [ ] The h1, the gate section (L119–129), and `history.js` are byte-identical to before this task.
- [ ] `uv run pytest` green; lint + types clean; coverage >90%.