diff --git a/.agents/phases/todo/101_tokens_page_overhaul/00_phase.md b/.agents/phases/complete/101_tokens_page_overhaul/00_phase.md similarity index 100% rename from .agents/phases/todo/101_tokens_page_overhaul/00_phase.md rename to .agents/phases/complete/101_tokens_page_overhaul/00_phase.md diff --git a/.agents/phases/todo/101_tokens_page_overhaul/01_regenerate_api.md b/.agents/phases/complete/101_tokens_page_overhaul/01_regenerate_api.md similarity index 100% rename from .agents/phases/todo/101_tokens_page_overhaul/01_regenerate_api.md rename to .agents/phases/complete/101_tokens_page_overhaul/01_regenerate_api.md diff --git a/.agents/phases/todo/101_tokens_page_overhaul/02_two_tables_search_required_name.md b/.agents/phases/complete/101_tokens_page_overhaul/02_two_tables_search_required_name.md similarity index 100% rename from .agents/phases/todo/101_tokens_page_overhaul/02_two_tables_search_required_name.md rename to .agents/phases/complete/101_tokens_page_overhaul/02_two_tables_search_required_name.md diff --git a/.agents/phases/todo/101_tokens_page_overhaul/03_regenerate_ui.md b/.agents/phases/complete/101_tokens_page_overhaul/03_regenerate_ui.md similarity index 100% rename from .agents/phases/todo/101_tokens_page_overhaul/03_regenerate_ui.md rename to .agents/phases/complete/101_tokens_page_overhaul/03_regenerate_ui.md diff --git a/.agents/phases/todo/101_tokens_page_overhaul/04_e2e_tokens_page.md b/.agents/phases/complete/101_tokens_page_overhaul/04_e2e_tokens_page.md similarity index 100% rename from .agents/phases/todo/101_tokens_page_overhaul/04_e2e_tokens_page.md rename to .agents/phases/complete/101_tokens_page_overhaul/04_e2e_tokens_page.md diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.err b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.md b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.md new file mode 100644 index 0000000..36302ea --- /dev/null +++ b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.md @@ -0,0 +1,20 @@ +All gates verified green — no defects found, nothing to fix. Final report: + +## Phase 101 — final verification pass (all tasks already complete; verified, not re-implemented) + +**Verified against the working tree** (task files 01–04 present in `complete/`): +- Active/revoked table split (Status column gone, section hidden while 0 revoked, per-table search with query state surviving re-renders) in `frontend/index.html` + `tokens.js` +- `generateToken()` refuses blank/whitespace names (`Give the token a name first.`, no request); `|| "token"` fallback deleted +- Atomic rotation: `regenerate_token` service + `POST /api/tokens/{id}/regenerate` (201 new-plaintext-once / 404 / 409 / router-wide 403) + `TokenListItem.revoked_at` (D5) +- Regenerate two-step confirm UI + CSS (`.token-regenerate`, neutral hover, no new hue); A4 pins intact + +**Test / lint / coverage results:** +- `uv run pytest` → **2065 passed** +- `uv run pytest --cov=app --cov-report=term-missing` → **TOTAL 99%** (>90% ✓) +- `uv run ruff check . && uv run pyright` → clean (0 errors) +- `uv run pytest tests/e2e/test_tokens_page.py -v --no-cov` → **4 passed** (isolation, DB up) +- Regression, each in isolation: `test_api_tokens.py` **9 passed**, `test_admin_auth.py` **6 passed**, `test_shared_header.py` **6 passed**, `test_theme_semantic_completion.py` **8 passed** (its revoked-pill pin was correctly re-scoped to the revoked table in this phase) + +**Completion criteria:** 1 ✓ split+search (E2E 1–2) · 2 ✓ required name (E2E 3 + source pin) · 3 ✓ rotation end-to-end, old token refused at gate (E2E 4 + API 404/409 pinned) · 4 ✓ A4 holds (list carries no plaintext/hashes) · 5 ✓ suite/coverage/lint green · 6 ✓ E2E + regressions green in isolation · 7 commit left to the harness per executor rules (all changes uncommitted in the working tree) + +**Deviations:** none. Next pending phase: `98_sync_summary_visibility`. diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.validate b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.validate new file mode 100644 index 0000000..564acd4 --- /dev/null +++ b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__00_phase.a1.validate @@ -0,0 +1,96 @@ +........................................................................ [ 3%] +........................................................................ [ 6%] +........................................................................ [ 10%] +........................................................................ [ 13%] +........................................................................ [ 17%] +........................................................................ [ 20%] +........................................................................ [ 24%] +........................................................................ [ 27%] +........................................................................ [ 31%] +........................................................................ [ 34%] +........................................................................ [ 38%] +........................................................................ [ 41%] +........................................................................ [ 45%] +........................................................................ [ 48%] +........................................................................ [ 52%] +........................................................................ [ 55%] +........................................................................ [ 59%] +........................................................................ [ 62%] +........................................................................ [ 66%] +........................................................................ [ 69%] +........................................................................ [ 73%] +........................................................................ [ 76%] +........................................................................ [ 80%] +........................................................................ [ 83%] +........................................................................ [ 87%] +........................................................................ [ 90%] +........................................................................ [ 94%] +........................................................................ [ 97%] +................................................. [100%] +=============================== warnings summary =============================== +.venv/lib/python3.13/site-packages/fastapi/testclient.py:1 + /var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead. + from starlette.testclient import TestClient as TestClient # noqa + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +================================ tests coverage ================================ +_______________ coverage: platform linux, python 3.13.13-final-0 _______________ + +Name Stmts Miss Cover +-------------------------------------------------- +app/__init__.py 1 0 100% +app/api/__init__.py 0 0 100% +app/api/auth.py 52 0 100% +app/api/chat.py 181 0 100% +app/api/chats.py 110 0 100% +app/api/config.py 13 0 100% +app/api/doc_drafts.py 94 0 100% +app/api/docs.py 127 1 99% +app/api/git_sources.py 229 0 100% +app/api/health.py 10 0 100% +app/api/steering.py 42 0 100% +app/api/suggestions.py 29 0 100% +app/api/sync.py 115 0 100% +app/api/tokens.py 40 0 100% +app/api/ui_settings.py 55 0 100% +app/config.py 140 0 100% +app/core/__init__.py 0 0 100% +app/core/auth.py 45 0 100% +app/core/caching.py 124 0 100% +app/core/debugging.py 29 2 93% +app/core/docs_push.py 39 0 100% +app/core/errors.py 5 0 100% +app/core/logging.py 13 0 100% +app/core/rate_limit.py 44 0 100% +app/core/security_headers.py 20 0 100% +app/core/theming.py 38 0 100% +app/core/tokens.py 44 0 100% +app/db.py 21 0 100% +app/main.py 66 0 100% +app/models.py 125 0 100% +app/rag/__init__.py 0 0 100% +app/rag/agent.py 316 1 99% +app/rag/archive_upload.py 128 0 100% +app/rag/chunker.py 206 4 98% +app/rag/folder_summaries.py 121 0 100% +app/rag/git_sources.py 14 0 100% +app/rag/importer.py 190 3 98% +app/rag/llm.py 243 1 99% +app/rag/overview.py 71 0 100% +app/rag/prompts.py 88 0 100% +app/rag/retriever.py 150 3 98% +app/rag/scaffolding.py 55 0 100% +app/rag/source_removal.py 41 0 100% +app/rag/sources_meta.py 16 0 100% +app/rag/suggestions.py 27 0 100% +app/rag/summarizer.py 24 0 100% +app/schemas.py 307 0 100% +-------------------------------------------------- +TOTAL 3848 15 99% +coverage gate: app/ 99% (>90%) OK +All checks passed! +0 errors, 0 warnings, 0 informations +WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414). +Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest` + +validation OK diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.err b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.md b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.md new file mode 100644 index 0000000..eb44c4b --- /dev/null +++ b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.md @@ -0,0 +1,19 @@ +Task 01 complete — everything green. + +**Implemented** +- `app/core/tokens.py`: `TokenAlreadyRevoked` exception + `regenerate_token(db, token_id)` — atomic rotation (revoke-stamp + same-label successor create in one flush-only unit; caller owns the single commit), `None` for unknown id; module docstring carries the rotation/A4 contract. +- `app/api/tokens.py`: `POST /api/tokens/{id}/regenerate` → 201 `TokenCreated` (new row's one plaintext moment), 404 `token not found`, 409 `token already revoked`; router-wide `require_admin` covers it; `list_tokens` now passes `revoked_at`. +- `app/schemas.py`: `TokenListItem.revoked_at: datetime | None = None` (D5, wire-additive, docstring pinned). + +**Tests** +- Unit (`tests/unit/test_tokens.py`): rotation matrix — new row/same label/well-formed plaintext/hash round-trip, old row stamped, old plaintext dead, missing → `None`, revoked → raises, rollback undoes BOTH writes (service never commits). +- Integration (`tests/integration/test_tokens_api.py`): 201 rotation (old row revoked w/ ISO `revoked_at`, new row active + newer `created_at` via deterministic gap, A4 list stays secret-free), 404, 409 (row untouched), 403 anonymous on all routes + 403 token-user; phase-79 list pins updated in place for the new field. + +**Results** +- `uv run pytest --cov=app --cov-report=term-missing` → 2060 passed, TOTAL 99% (>90%; tokens modules 100%) +- `uv run ruff check .` → clean; `uv run pyright` → 0 errors +- Regression: `tests/integration/test_auth_api.py` (17) and `uv run pytest tests/e2e/test_api_tokens.py --no-cov` (9) green in isolation + +**Decisions**: none beyond spec; kept house conventions (service flushes/endpoint commits, one message per 404/409, docstring-carried contracts). + +**Next pending task**: `.agents/phases/todo/101_tokens_page_overhaul/02_two_tables_search_required_name.md` diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.validate b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.validate new file mode 100644 index 0000000..97c64f7 --- /dev/null +++ b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__01_regenerate_api.a1.validate @@ -0,0 +1,96 @@ +........................................................................ [ 3%] +........................................................................ [ 6%] +........................................................................ [ 10%] +........................................................................ [ 13%] +........................................................................ [ 17%] +........................................................................ [ 20%] +........................................................................ [ 24%] +........................................................................ [ 27%] +........................................................................ [ 31%] +........................................................................ [ 34%] +........................................................................ [ 38%] +........................................................................ [ 41%] +........................................................................ [ 45%] +........................................................................ [ 48%] +........................................................................ [ 52%] +........................................................................ [ 55%] +........................................................................ [ 59%] +........................................................................ [ 62%] +........................................................................ [ 66%] +........................................................................ [ 69%] +........................................................................ [ 73%] +........................................................................ [ 76%] +........................................................................ [ 80%] +........................................................................ [ 83%] +........................................................................ [ 87%] +........................................................................ [ 90%] +........................................................................ [ 94%] +........................................................................ [ 97%] +............................................ [100%] +=============================== warnings summary =============================== +.venv/lib/python3.13/site-packages/fastapi/testclient.py:1 + /var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead. + from starlette.testclient import TestClient as TestClient # noqa + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +================================ tests coverage ================================ +_______________ coverage: platform linux, python 3.13.13-final-0 _______________ + +Name Stmts Miss Cover +-------------------------------------------------- +app/__init__.py 1 0 100% +app/api/__init__.py 0 0 100% +app/api/auth.py 52 0 100% +app/api/chat.py 181 0 100% +app/api/chats.py 110 0 100% +app/api/config.py 13 0 100% +app/api/doc_drafts.py 94 0 100% +app/api/docs.py 127 1 99% +app/api/git_sources.py 229 0 100% +app/api/health.py 10 0 100% +app/api/steering.py 42 0 100% +app/api/suggestions.py 29 0 100% +app/api/sync.py 115 0 100% +app/api/tokens.py 40 0 100% +app/api/ui_settings.py 55 0 100% +app/config.py 140 0 100% +app/core/__init__.py 0 0 100% +app/core/auth.py 45 0 100% +app/core/caching.py 124 0 100% +app/core/debugging.py 29 2 93% +app/core/docs_push.py 39 0 100% +app/core/errors.py 5 0 100% +app/core/logging.py 13 0 100% +app/core/rate_limit.py 44 0 100% +app/core/security_headers.py 20 0 100% +app/core/theming.py 38 0 100% +app/core/tokens.py 44 0 100% +app/db.py 21 0 100% +app/main.py 66 0 100% +app/models.py 125 0 100% +app/rag/__init__.py 0 0 100% +app/rag/agent.py 316 1 99% +app/rag/archive_upload.py 128 0 100% +app/rag/chunker.py 206 4 98% +app/rag/folder_summaries.py 121 0 100% +app/rag/git_sources.py 14 0 100% +app/rag/importer.py 190 3 98% +app/rag/llm.py 243 1 99% +app/rag/overview.py 71 0 100% +app/rag/prompts.py 88 0 100% +app/rag/retriever.py 150 3 98% +app/rag/scaffolding.py 55 0 100% +app/rag/source_removal.py 41 0 100% +app/rag/sources_meta.py 16 0 100% +app/rag/suggestions.py 27 0 100% +app/rag/summarizer.py 24 0 100% +app/schemas.py 307 0 100% +-------------------------------------------------- +TOTAL 3848 15 99% +coverage gate: app/ 99% (>90%) OK +All checks passed! +0 errors, 0 warnings, 0 informations +WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414). +Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest` + +validation OK diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__02_two_tables_search_required_name.a1.err b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__02_two_tables_search_required_name.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__02_two_tables_search_required_name.a1.md b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__02_two_tables_search_required_name.a1.md new file mode 100644 index 0000000..7550038 --- /dev/null +++ b/.agents/reports/101_tokens_page_overhaul/101_tokens_page_overhaul__02_two_tables_search_required_name.a1.md @@ -0,0 +1,14 @@ +All green. Task 02 is complete. + +**Implemented (phase 101, task 02 — two tables, per-table search, required name):** +- `frontend/index.html` `#view-tokens`: 4-column active table (Status `