phase: 96_oneshot_resilience
All checks complete. Final report: **Phase 96 (one-shot resilience) — final verification pass, all green** (all 4 task files already in `complete/`; verified the working-tree implementation against the design) - `LLMClient.chat()` empty-content retry (D1–D3) via `_chat_once` + `_EmptyContentError` (carries `finish_reason`), under `BOR_LLM_RETRIES`/`BOR_LLM_RETRY_DELAY` — verified in diff - `missing_folder_summaries()` + `generate_folder_summaries(only_missing=…)` — verified; `folder_summary_table_empty` deleted, both sync gates switched to the gap probe - `.env.example` comments updated (chat-turn stream + one-shot summary calls) **Test / lint / coverage results** - `uv run pytest --cov=app --cov-report=term-missing` → **1988 passed**, coverage **99%** (gate >90%) - `uv run pytest tests/e2e/test_oneshot_llm_retry.py -v --no-cov` → **2 passed** (isolated) - Regressions, each isolated: `test_ls_tree_drilldown` 3 passed, `test_sync_button` 3 passed, `test_local_directory_sources` 3 passed, `test_llm_retry` 4 passed - `uv run ruff check . && uv run pyright` → clean (0 errors) **Completion criteria:** retry-then-recover unit-pinned ✓ · exhaustion + `BOR_LLM_RETRIES=0` byte-identical ✓ · streaming path untouched ✓ · gap-fill both sync paths, other rows byte-identical incl. `updated_at` ✓ · no-gap zero-burn ✓ · phase E2E green ✓ · regression E2Es green ✓ · full suite + >90% + lint/types ✓ · no completed-phase behavior change (full suite green) ✓. Commit left to the harness per executor rules (working tree, 16 files). **Deviations:** none. **Next pending phase:** `97_kb_tree_catalog`.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
All checks complete. Final report:
|
||||
|
||||
**Phase 96 (one-shot resilience) — final verification pass, all green** (all 4 task files already in `complete/`; verified the working-tree implementation against the design)
|
||||
|
||||
- `LLMClient.chat()` empty-content retry (D1–D3) via `_chat_once` + `_EmptyContentError` (carries `finish_reason`), under `BOR_LLM_RETRIES`/`BOR_LLM_RETRY_DELAY` — verified in diff
|
||||
- `missing_folder_summaries()` + `generate_folder_summaries(only_missing=…)` — verified; `folder_summary_table_empty` deleted, both sync gates switched to the gap probe
|
||||
- `.env.example` comments updated (chat-turn stream + one-shot summary calls)
|
||||
|
||||
**Test / lint / coverage results**
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → **1988 passed**, coverage **99%** (gate >90%)
|
||||
- `uv run pytest tests/e2e/test_oneshot_llm_retry.py -v --no-cov` → **2 passed** (isolated)
|
||||
- Regressions, each isolated: `test_ls_tree_drilldown` 3 passed, `test_sync_button` 3 passed, `test_local_directory_sources` 3 passed, `test_llm_retry` 4 passed
|
||||
- `uv run ruff check . && uv run pyright` → clean (0 errors)
|
||||
|
||||
**Completion criteria:** retry-then-recover unit-pinned ✓ · exhaustion + `BOR_LLM_RETRIES=0` byte-identical ✓ · streaming path untouched ✓ · gap-fill both sync paths, other rows byte-identical incl. `updated_at` ✓ · no-gap zero-burn ✓ · phase E2E green ✓ · regression E2Es green ✓ · full suite + >90% + lint/types ✓ · no completed-phase behavior change (full suite green) ✓. Commit left to the harness per executor rules (working tree, 16 files).
|
||||
|
||||
**Deviations:** none. **Next pending phase:** `97_kb_tree_catalog`.
|
||||
@@ -0,0 +1,95 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 57%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 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 50 0 100%
|
||||
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 28 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 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 124 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 120 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 279 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3718 14 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
|
||||
@@ -0,0 +1,10 @@
|
||||
All checks pass. The diff is confined to `_EmptyContentError` + `_chat_once` + `chat()` in `app/rag/llm.py`, the `.env.example` comments, and the unit test file — the streaming path is byte-identical.
|
||||
|
||||
**Task 01 report**
|
||||
|
||||
- `LLMClient.chat()` now retries empty-content replies (the 2026-09-11 incident class) under the existing `BOR_LLM_RETRIES`/`BOR_LLM_RETRY_DELAY` policy: single-attempt body extracted verbatim into private `_chat_once()`; empty replies raise internal `_EmptyContentError` (carries `finish_reason`, never escapes the client); `chat()` logs one `WARNING` per retry (model, `finish_reason`, `attempt n/N`) + flat sleep, then raises `LLMError("…returned empty content on all N attempts — refusing to store a silent summary")`; `llm_retries=0` keeps the pre-phase-96 message byte-identical. Choiceless/transport errors still raise immediately (no app-level retry).
|
||||
- `chat()` docstring extended with the D1–D3 retry policy; `.env.example` comments on both knobs now name the phase-67 stream + phase-96 one-shot coverage. No new settings.
|
||||
- Unit pins added in `tests/unit/test_llm_client.py`: empty-then-success (2 attempts, 1 sleep, 1 warning with `finish_reason=length`/`attempt 1/4`), all-empty exhaustion (4 attempts/3 sleeps + exact message; `llm_retries=1` names 2), first-success (1 call, 0 sleeps), no-choices and transport (no retry), `llm_retries=0` legacy message asserted as exact string, flat-delay (never backoff), explicit-model warning, `finish_reason=None` log safety; the two pre-existing empty-content pins moved to the kill-switch setting.
|
||||
- Tests: `uv run pytest tests/unit/test_llm_client.py -v` → 66 passed; full `uv run pytest -v` → **1975 passed**, 0 failed; `uv run pytest --cov=app` → app/ 99% (llm.py 99%, only the unreachable guard line uncovered); `uv run ruff check .` clean; `uv run pyright` → 0 errors, 0 warnings.
|
||||
- Phase-67 streaming retry suite (12 tests) green; no changes outside `chat()`/`_chat_once` in `app/rag/llm.py`. Changes left uncommitted in the working tree per harness protocol.
|
||||
- Next pending task: `.agents/phases/todo/96_oneshot_resilience/02_gapfill_generator.md`
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 51%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 69%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 94%]
|
||||
........................................................................ [ 98%]
|
||||
............................... [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 50 0 100%
|
||||
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 110 0 100%
|
||||
app/api/tokens.py 28 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 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 124 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 110 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 279 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3703 14 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
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
All deletions are the intended refactor; nothing else in the module changed. Task 02 is complete and green.
|
||||
|
||||
## Report — Phase 96, Task 02 (gap-fill generator)
|
||||
|
||||
**Implemented**
|
||||
- `app/rag/folder_summaries.py`: new `missing_folder_summaries(db)` — candidate folders (generator's exact catalogue query → `group_by_folder` → ≥`MIN_DOCS_PER_FOLDER`) minus stored keys (one bounded select), sorted `(source, folder_path)`, `[]` on no gap
|
||||
- `generate_folder_summaries(…, only_missing=False)`: restricts iteration to missing keys derived from the same catalogue pass (one stored-key select, no second catalogue query); existing rows byte-identical (text AND `updated_at`), prune pass runs in both modes vs the full candidate set; default path behavior-identical
|
||||
- Private helpers `_catalog_rows` / `_candidates` / `_stored_keys` so gate and fill share one concept; `folder_summary_table_empty` left in place (task 03 removes it); docstrings updated per task contract
|
||||
- `tests/unit/test_folder_summaries.py`: +10 pins — missing-set shapes (fresh/full/one-deleted/empty-KB/single-doc/stale-row) and `only_missing` (exact fill in sorted order with `updated_at` byte-identity, zero-burn no-gap, stale-row prune, fail-soft); all 32 pre-existing tests unmodified
|
||||
|
||||
**Results**
|
||||
- `uv run pytest tests/unit/test_folder_summaries.py -v --no-cov` → 42 passed
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → 1985 passed, TOTAL 99% (>90%); `folder_summaries.py` 100%
|
||||
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors
|
||||
|
||||
**Decisions**: prune compares against the full candidate map (not the restricted key set) so `only_missing` can never wrongly delete present rows — empirically verified `db.get` returns `None` for behind-the-session deletes, and sync paths use fresh sessions.
|
||||
|
||||
**Next pending task**: `03_sync_gates.md` (gap gate in `scripts/import_docs.py` + `app/api/sync.py`).
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 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 50 0 100%
|
||||
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 110 0 100%
|
||||
app/api/tokens.py 28 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 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 124 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 122 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 279 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3715 14 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
|
||||
@@ -0,0 +1,11 @@
|
||||
All completion criteria met. Final report:
|
||||
|
||||
**Task 03 (sync gates) — complete**
|
||||
|
||||
- **`scripts/import_docs.py`**: unchanged-walk gate now `folders_due = bool(_folder_summaries_gap())` (task 02's `missing_folder_summaries`); gap → `generate_folder_summaries(…, only_missing=True)`; summary line token gains ` (gap-fill)` suffix on the targeted-fill path (changed runs and `skipped` rendering byte-identical to phase 94); `--limit` skip, module + `_run` docstrings updated.
|
||||
- **`app/api/sync.py`**: unchanged resync → gap probe; non-empty → `only_missing=True` fill + `sync: folder_summaries gap-fill missing=… stats=…` log; empty → existing skip log; changed → full regen (unchanged); module + block docstrings updated; `sync_status` shape untouched.
|
||||
- **`app/rag/folder_summaries.py`**: `folder_summary_table_empty` deleted — grep confirms zero remaining references; imports replaced in both sync modules.
|
||||
- **Tests**: new integration pins — script unchanged+gap (exactly 1 `FOLDER_SUMMARY_MODE` call, other rows byte-identical incl. `updated_at`, `(gap-fill)` token), script changed→full (call count == candidate count, all re-stamped), API unchanged+gap (targeted fill + gap-fill log, detail key set pinned); first-run subsumption pins now assert the `(gap-fill)` path; unit gate test moved to `missing_folder_summaries`.
|
||||
- **Defects fixed in completed work**: stale `generate_folder_summaries` fakes in `test_import_docs_git.py` (3 failures), `test_sync_api.py` (`FakeFolderSummaries` + `only_missing_flags`), and `test_sync_button.py` (signature + DB-free `missing_folder_summaries` seam).
|
||||
- **Results**: `uv run pytest --cov=app --cov-report=term-missing` → 1988 passed, TOTAL 99% (`app/api/sync.py` 100%, `app/rag/folder_summaries.py` 100%); `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors. Phase-94/53 contracts (zero-burn, bump gating, `--limit` skip, status shape) verified green.
|
||||
- **Deviations**: none. Next pending task: `04_e2e_oneshot_retry.md`.
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 57%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 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 50 0 100%
|
||||
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 28 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 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 124 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 120 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 279 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3718 14 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
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
Task 04 complete — all gates green.
|
||||
|
||||
**Implemented**
|
||||
- `tests/e2e/mock_llm.py`: incident-shape injection in the `FOLDER_SUMMARY_MODE` path — `_folder_summary_incident()` keyed by the `Folder: …` label (existing parse); `/e2e_empty_once` → first non-stream POST returns the 2026-09-11 envelope (`content=""`, `finish_reason="length"`), later POSTs normal; `/e2e_empty_always` → every POST empty; per-label counter resets after the success it guards (phase-67 pattern); module docstring + branch comment updated
|
||||
- `tests/e2e/test_oneshot_llm_retry.py` (new, port 8138): 1 local source, 3 ≥2-doc folders; sync #1 → `ls oneshot` drill-down pins retry-recovered `e2e_empty_once` row, normal row, bare `e2e_empty_always` line (no `: …` suffix), sync success; deleted `normal` row → unchanged sync #2 → row healed, `e2e_empty_once` `updated_at` untouched (targeted fill), `e2e_empty_always` still absent, sync green
|
||||
|
||||
**Results**
|
||||
- `uv run pytest tests/e2e/test_oneshot_llm_retry.py -v --no-cov` → 2 passed (re-run green — deterministic reset)
|
||||
- Regressions in isolation: `test_ls_tree_drilldown.py` 3 passed, `test_sync_button.py` 3, `test_local_directory_sources.py` 3, `test_llm_retry.py` 4
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → 1988 passed, TOTAL coverage 99% (>90%)
|
||||
- `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors, 0 warnings
|
||||
|
||||
**Decisions**: injection lives in the non-stream response path (where the envelope forms) with the label/counter logic beside the `FOLDER_SUMMARY_MODE` branch; sync driven via httpx (house `test_sync_button`/phase-94 pattern), drill turns via Playwright SSE hook (phase-94 lens). No app-code changes needed (tasks 01–03 already in tree). No commit made — left to the harness per pipeline rules.
|
||||
|
||||
**Next pending task**: none in phase 96 (04 was the last); no other phases in `todo/`.
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 57%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 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 50 0 100%
|
||||
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 28 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 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 124 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 120 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 279 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3718 14 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
|
||||
Reference in New Issue
Block a user