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
5.8 KiB
name, description
| name | description |
|---|---|
| restore-test-db | 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_dumping
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
psqlinside the db container (brain-of-reese_db_1), not with a hostpsql— the container's psql is 17.x, matching the dump (newer dumps use the\restrictmetacommand 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)
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:
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):
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)
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
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)
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 theDROP SCHEMAcommand from step 3.psql: /dev/stdin:N: unknown command '\restrict'— you ran a hostpsql; use the container's, per the rules.- load succeeds but counts are wrong — compare the dump's
alembic_version(step 1) anddocumentsrow 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 — runuv run alembic current; if the dump was older than head, step 1'salembic upgrade headwas the missing piece.