phase: 168_admin_settings_panel
Build and Push Containers / build-and-push-app (push) Successful in 4m4s
Build and Push Containers / build-and-push-db (push) Successful in 15s

**Phase 168 — Admin Settings panel — final verification: PASS**

1. **Implemented/verified:** `/settings.html` (admin-only) with the 75-field catalogue (`app/core/settings_catalog.py`), DB-over-env overrides in Postgres (`app_settings`, migration 0028 at head, `settings_overlay.py` resolver, `app/api/admin_settings.py` — 4 admin-only routes), live-apply on save with no restart + restart-required badges, Reset/Clear all, write-only secrets, `.env`-never-written, `BOR_SETTINGS_DB=0` kill switch.
2. **Phase E2E: 12/12** — run with `E2E_APP_PORT=8200` (ports 8123/8124 are held by an unrelated "undercooked" project; no process killed, no code change — the documented env override).
3. **Regression set: all 7 suites green in isolation** (theme tab, API tokens, configurable brand, global tuning, admin auth, cache busting, wide desktop column — 38 tests).
4. **Full suite: unit+integration exit 0 (4066 passed), app/ coverage 99%** (gate >90%); **ruff clean, pyright 0 errors / 0 warnings.**
5. **Log contract (rule 10) verified live:** per-turn + per-response byte-budget lines present; settings write lines carry key + action, **never the value**.
6. **Byte-budget audit: all endpoints under the 262,144 B budget**; settings catalogue 23,513 B (gzip 3,326).
7. **Defect fixed (one):** criterion 5 had no integration pin — added `test_bad_row_inserted_directly_never_bricks_boot` to `tests/integration/test_admin_settings_api.py` (malformed row inserted directly → fresh `create_app()` boots, row skipped with logged reason, rest of table applies, `/api/health` 200) — 12/12 green.
8. **Docs pass:** `README.md` and `AGENTS.md` reviewed in full — both consistent with the as-built feature (Settings page table, Settings section, Configuration-reference note, `.env.example` block); **no changes required**.
9. **Cleanup:** audit app killed (by PID); `app_settings` left empty (0 rows); all changes left in the working tree (no commit, per protocol).
10. **Completion criteria:** all 7 checkboxes verified green (criterion 7's commit is the harness's).
11. **Next pending phase:** `170_edit_bubble_sizing`.
This commit is contained in:
2026-10-10 01:05:14 -04:00
parent abe7388dda
commit 1200437bf8
79 changed files with 7148 additions and 378 deletions
+13 -1
View File
@@ -128,8 +128,11 @@ def test_view_map_covers_the_shell_paths() -> None:
assert '"/theme.html": "theme"' in view_body, (
"phase 91 task 04 folds the Theme view into the shell"
)
assert '"/settings.html": "settings"' in view_body, (
"phase 168 task 05 folds the Settings view into the shell"
)
# The view names are the #view-<name> section slugs in index.html.
for name in ("chat", "tuning", "history", "tokens", "theme"):
for name in ("chat", "tuning", "history", "tokens", "theme", "settings"):
assert f'id="view-{name}"' in _html(), f"missing the #view-{name} section"
@@ -226,6 +229,10 @@ def test_only_non_chat_views_have_lazy_modules() -> None:
assert 'theme: () => import("./theme.js")' in mods_body, (
"the Theme view module is lazy-imported on first show (phase 91)"
)
assert 'settings: () => import("./settings.js")' in mods_body, (
"the Settings view module is lazy-imported on first show "
"(phase 168, a static specifier the bundle inlines)"
)
assert '"chat"' not in mods_body, "the chat view has no lazy module"
assert 'import("./app.js")' not in js, "app.js must never be lazy-imported"
@@ -288,6 +295,11 @@ def test_router_writes_active_state_title_and_meta() -> None:
"Set the palette and branding — the theme is baked into every served page, "
"live on the first paint."
) in js
assert 'settings: "Settings · Brain of Reese"' in js
assert (
"Edit any application setting — a saved value wins over the environment, "
"live on save; reset hands control back."
) in js
# The brand composition (phase 39's window.BOR_BRAND, read at
# write time — never a hardcoded stamp).
assert 'window.BOR_BRAND || "Brain of Reese"' in js