feat: phases 77–80 — navbar view refresh, static background, API tokens, history suggestion chips
Single consolidated commit for four completed, validated phases (77, 78, 79, 80). The pipeline run left all work uncommitted because the harness commits only with PHASE_COMMIT=1 while child executors are forbidden from committing; the phases themselves all passed validation and moved to .agents/phases/complete/. Phase 77 — navbar view refresh - router.js dispatches bor:view-refresh on re-show / active re-click / popstate (gated on wasMounted; first show and boot exempt) - History / RAG / Sources / Tuning re-fetch on refresh (admin branch); Chat deliberately excluded (stream survival) - History "Refresh" button (admin-only, in-flight disable + status line) - New story suite tests/e2e/test_navbar_refresh.py (7 tests) Phase 78 — static background - Removed the animated glow layers; static 44px grid over the flat --bg canvas; default and reduced-motion renders byte-identical - Updated background/theme E2E suites; removed bg-glow test pins Phase 79 — API tokens - api_tokens model + migration 0012; hash-only token service - Admin tokens API + Tokens admin view; POST /api/token-auth; live-revoking require_user on chat / suggestions / document content - Frontend token gate with localStorage cache; anonymous E2E suites migrated to token login - New story suite tests/e2e/test_api_tokens.py (9 tests) Phase 80 — history suggestion chips - last_questions() endpoint with SEED fallback; startNewChat() refetch - Seed-semantics docs (config.py, .env.example, README) - Integration state matrix + E2E suite rewritten to the 4 chip states Also included: phase-76 report artifacts and the repo restore-test-db skill (previously untracked), scripts/* ruff fixes from phase 77. Final gate state (phase 80 final pass, covers everything above): - uv run pytest --cov=app → 1637 passed, 0 failed, app/ coverage 99% - uv run ruff check . && uv run pyright → clean, 0 errors - Per-phase story E2E suites green in isolation
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
---
|
||||
name: restore-test-db
|
||||
description: Restores the large 1,000-document test knowledge base (the live-KB replica snapshot at data/bor_live_kb_replica.dump.sql) into the app's Postgres database in one atomic transaction — wipes the database's current contents, no re-embedding, no app code changes. Use when the user asks to restore the test database, the 1,000-document KB, or the big/live replica KB (e.g. "restore the test database", "put the 1000-doc KB back"). Do not confuse with the 8-document tool-calling fixture KB, which scripts/restore_test_kb.py restores.
|
||||
---
|
||||
|
||||
# Restore the 1,000-Document Test KB
|
||||
|
||||
Load `data/bor_live_kb_replica.dump.sql` (a full 99 MB `pg_dump` —
|
||||
schema **and** data — of the live KB replica) into the app database
|
||||
(`brain_of_reese`, per `BOR_DATABASE_URL` in `.env`). The embeddings come
|
||||
with the dump, so there is **no re-embedding, no git clone, no app code
|
||||
change** — the whole known state (documents, chunks + embeddings, source
|
||||
registry, KB overview, alembic version) lands in a few seconds.
|
||||
|
||||
The dump is a local artifact: `data/` is gitignored and the dump is
|
||||
**never committed**. It is not in git — if it is missing on a fresh
|
||||
clone, stop and ask the user for it (it can only be made by `pg_dump`ing
|
||||
the live/`bor_eval` KB).
|
||||
|
||||
## Rules (non-negotiable)
|
||||
|
||||
- **The restore is destructive** — it wipes the current contents of the
|
||||
app database. Always take the disposable backup in step 2 first, even
|
||||
when the database looks empty.
|
||||
- **Do not edit app code** (`app/`, `tests/`, `alembic/`). This skill
|
||||
swaps database contents, nothing else.
|
||||
- **Run `psql` inside the db container** (`brain-of-reese_db_1`), not
|
||||
with a host `psql` — the container's psql is 17.x, matching the dump
|
||||
(newer dumps use the `\restrict` metacommand that old host psqls
|
||||
choke on).
|
||||
- This KB and the 8-document tool-calling fixture KB
|
||||
(`scripts/restore_test_kb.py`) share the same database and overwrite
|
||||
each other. Say which one is loaded in the summary.
|
||||
|
||||
## Procedure
|
||||
|
||||
All commands run from the repo root.
|
||||
|
||||
### 1. Preconditions (fast fail)
|
||||
|
||||
```bash
|
||||
podman compose up -d db
|
||||
ls -lh data/bor_live_kb_replica.dump.sql # must exist, ~99 MB
|
||||
```
|
||||
|
||||
Check the dump's schema version against the current head:
|
||||
|
||||
```bash
|
||||
grep -A1 '^COPY public.alembic_version' data/bor_live_kb_replica.dump.sql | tail -1
|
||||
uv run alembic heads
|
||||
```
|
||||
|
||||
The two must match (the 2026-09-05 snapshot carries `0011`). If the dump
|
||||
is **older** than head, proceed and run `uv run alembic upgrade head`
|
||||
after step 3. If the dump is **newer** than head, the local code is
|
||||
behind — stop and flag it to the user.
|
||||
|
||||
### 2. Disposable safety backup
|
||||
|
||||
Seconds, in `/tmp` (never committed):
|
||||
|
||||
```bash
|
||||
podman exec brain-of-reese_db_1 pg_dump -U reese brain_of_reese -Fc \
|
||||
> /tmp/pre_restore_$(date +%Y%m%d_%H%M%S).dump
|
||||
```
|
||||
|
||||
### 3. Reset the schema, load the dump (one transaction)
|
||||
|
||||
```bash
|
||||
podman exec brain-of-reese_db_1 psql -U reese -d brain_of_reese -c \
|
||||
"DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO PUBLIC;"
|
||||
|
||||
podman exec -i brain-of-reese_db_1 psql -U reese -d brain_of_reese \
|
||||
-v ON_ERROR_STOP=1 --single-transaction -q -f /dev/stdin \
|
||||
< data/bor_live_kb_replica.dump.sql
|
||||
```
|
||||
|
||||
Why the schema reset: the dump contains plain `CREATE TABLE` (no
|
||||
`IF NOT EXISTS`, no `--clean`), so it can only load into an empty
|
||||
`public` schema. Why `--single-transaction` + `ON_ERROR_STOP`: a failed
|
||||
load rolls back instead of leaving a half-loaded KB. Known failure mode:
|
||||
the `DROP SCHEMA` is its own committed statement, so a failed load leaves
|
||||
an **empty** schema — that is fine, fix the cause and re-run step 3
|
||||
(the reset is idempotent).
|
||||
|
||||
### 4. Verify the fingerprint
|
||||
|
||||
```bash
|
||||
podman exec brain-of-reese_db_1 psql -U reese -d brain_of_reese -tAc \
|
||||
"select 'docs='||count(*) from documents
|
||||
union all select 'chunks='||count(*) from chunks
|
||||
union all select 'sources='||string_agg(distinct source, ',' order by source) from documents
|
||||
union all select 'alembic='||(select version_num from alembic_version);"
|
||||
```
|
||||
|
||||
Expected for the 2026-09-05 snapshot: **docs=1000, chunks=8866,
|
||||
sources=deploy,homelab,homepage,ServMon,skills,vibe-bot, alembic=0011**.
|
||||
If any number differs, the dump file is a different snapshot — report the
|
||||
actual numbers to the user; do not guess.
|
||||
|
||||
### 5. Dev-server check (only if it is running)
|
||||
|
||||
```bash
|
||||
pgrep -af "uvicorn app.main" && curl -s http://localhost:8000/api/health
|
||||
```
|
||||
|
||||
Expect `"db":"up"` — the SQLAlchemy pool reconnects fine across the
|
||||
schema reset, so no restart is normally needed. If the server misbehaves
|
||||
after the restore, restart it (`uv run uvicorn app.main:app --reload`).
|
||||
|
||||
### 6. Summary
|
||||
|
||||
One line per verified number (docs / chunks / sources / alembic), the
|
||||
wall time, and a reminder of which KB is loaded: this is the
|
||||
**1,000-document live replica**; the 8-document tool-calling fixture is
|
||||
brought back separately with `uv run python -m scripts.restore_test_kb`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **`database unreachable` / connection refused** — the db container is
|
||||
down; `podman compose up -d db`, then re-run from step 1.
|
||||
- **`relation "public.<table>" already exists`** — the schema was not
|
||||
reset (or a previous load failed after the reset rolled back); re-run
|
||||
the `DROP SCHEMA` command from step 3.
|
||||
- **`psql: /dev/stdin:N: unknown command '\restrict'`** — you ran a host
|
||||
`psql`; use the container's, per the rules.
|
||||
- **load succeeds but counts are wrong** — compare the dump's
|
||||
`alembic_version` (step 1) and `documents` row count
|
||||
(`sed -n '/^COPY public.documents/,/^\\./p' data/bor_live_kb_replica.dump.sql | wc -l`,
|
||||
minus 2) against the loaded numbers; a mismatch means the dump was
|
||||
truncated in transfer — ask the user for the original file.
|
||||
- **`schema not applied`-style errors from the app afterwards** — run
|
||||
`uv run alembic current`; if the dump was older than head, step 1's
|
||||
`alembic upgrade head` was the missing piece.
|
||||
Reference in New Issue
Block a user