phase: 194_sync_pending_count
**Phase 194 — final verification pass: all green.**
**Verified (all 5 tasks already complete; nothing re-implemented needed)**
- `app/rag/importer.py`: `_prescan_pending` + `_pending_hash_stmt` (scalar `documents.file_hash`, own session, ONE `asyncio.to_thread` span, REPLACES the stats pre-walk), `on_scan_progress`, `progress` pair = pending position, `0` branch = byte-identical phase-193 walk.
- `app/config.py`/`settings_catalog.py`/`.env.example`: `sync_pending_count=1` + validator; `app/api/sync.py`: `"scan"` phase, `scan_done`/`scan_total` (additive after `files_total`, kept at every terminal), forced/throttled RSS split; `frontend/assets/sources.js`: `fmtSyncPhaseLabel` scan branch first-arm, `fmtSyncLabel` untouched.
**Tests / lint / coverage (exact commands)**
- `uv run pytest --cov=app --cov-report=term-missing` → **4835 passed**, `app/` 99% (7240 stmts / 16 miss), exit 0
- `uv run pytest tests/e2e/test_sync_pending_count.py -v --no-cov` → **8 passed in 150.81s** (phase suite, isolated)
- 14 sync-lineage E2E suites, one pytest process each (`test_sync_remaining_count`, `…_chunk_progress`, `…_progress_box`, `…_peak_memory_visible`, `…_label_mobile`, `…_upload_progress`, `test_archive_upload_sources`, `…_image_progress`, `…_summary_visibility`, `…_status_freshness`, `test_smoke`, `test_fast_path_deferred_content`, `test_sync_session_reset`, `test_sync_git_freeze`) → **all exit 0**
- `uv run ruff check .` → All checks passed; `uv run pyright` → **0 errors**
**Completion criteria** — all met: `N remaining` = predicted change set (E2E arms 1/2/5, first import counts the walk, no-change → no count part); `scan` phase visible + flips to `import`, scan pair reset/kept at terminals (`test_sync_scan_phase.py`); `BOR_SYNC_PENDING_COUNT=0` walk semantics ("7 remaining" arm) + **negative refuses startup naming the field (verified live by importing `app.main`)**; pre-scan off-loop + cancel lands `cancelled` (integration pins); CLI/upload byte-identical (unedited pins green); payload additive (`_PRE_187_STATUS_KEYS | _MEMORY_KEYS | _SCAN_KEYS`); suite green, coverage >90%, lint/types clean.
**Documentation** — 3 fixes: README sync "States" bullet had an **unclosed parenthesis** (pre-existing, 193/194) and the scan-label "total is 0" clause was ambiguous about a `=0` run (it still counts the walk once the import starts); **AGENTS.md rule 17 had a stray `)`** (pre-existing from phase 191). Also verified consistency both directions for all 87 settings ↔ README ↔ `.env.example` ↔ settings catalog, the pages table ↔ `app/main.py` routes, no stale `BOR_` names, and README/AGENTS claims through phase 194.
**Notes/deviations** — no live-infra changes (prod sync knob ships default-on, no deployment touched); no git index/history commands run (all changes left in the working tree for the harness); commit criterion left to the harness as instructed.
**Next pending phase:** none — `.agents/phases/todo/` holds only `194_sync_pending_count`, which is now ready to move to `complete/`.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
**Phase 194 — final verification pass: all green.**
|
||||
|
||||
**Verified (all 5 tasks already complete; nothing re-implemented needed)**
|
||||
- `app/rag/importer.py`: `_prescan_pending` + `_pending_hash_stmt` (scalar `documents.file_hash`, own session, ONE `asyncio.to_thread` span, REPLACES the stats pre-walk), `on_scan_progress`, `progress` pair = pending position, `0` branch = byte-identical phase-193 walk.
|
||||
- `app/config.py`/`settings_catalog.py`/`.env.example`: `sync_pending_count=1` + validator; `app/api/sync.py`: `"scan"` phase, `scan_done`/`scan_total` (additive after `files_total`, kept at every terminal), forced/throttled RSS split; `frontend/assets/sources.js`: `fmtSyncPhaseLabel` scan branch first-arm, `fmtSyncLabel` untouched.
|
||||
|
||||
**Tests / lint / coverage (exact commands)**
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → **4835 passed**, `app/` 99% (7240 stmts / 16 miss), exit 0
|
||||
- `uv run pytest tests/e2e/test_sync_pending_count.py -v --no-cov` → **8 passed in 150.81s** (phase suite, isolated)
|
||||
- 14 sync-lineage E2E suites, one pytest process each (`test_sync_remaining_count`, `…_chunk_progress`, `…_progress_box`, `…_peak_memory_visible`, `…_label_mobile`, `…_upload_progress`, `test_archive_upload_sources`, `…_image_progress`, `…_summary_visibility`, `…_status_freshness`, `test_smoke`, `test_fast_path_deferred_content`, `test_sync_session_reset`, `test_sync_git_freeze`) → **all exit 0**
|
||||
- `uv run ruff check .` → All checks passed; `uv run pyright` → **0 errors**
|
||||
|
||||
**Completion criteria** — all met: `N remaining` = predicted change set (E2E arms 1/2/5, first import counts the walk, no-change → no count part); `scan` phase visible + flips to `import`, scan pair reset/kept at terminals (`test_sync_scan_phase.py`); `BOR_SYNC_PENDING_COUNT=0` walk semantics ("7 remaining" arm) + **negative refuses startup naming the field (verified live by importing `app.main`)**; pre-scan off-loop + cancel lands `cancelled` (integration pins); CLI/upload byte-identical (unedited pins green); payload additive (`_PRE_187_STATUS_KEYS | _MEMORY_KEYS | _SCAN_KEYS`); suite green, coverage >90%, lint/types clean.
|
||||
|
||||
**Documentation** — 3 fixes: README sync "States" bullet had an **unclosed parenthesis** (pre-existing, 193/194) and the scan-label "total is 0" clause was ambiguous about a `=0` run (it still counts the walk once the import starts); **AGENTS.md rule 17 had a stray `)`** (pre-existing from phase 191). Also verified consistency both directions for all 87 settings ↔ README ↔ `.env.example` ↔ settings catalog, the pages table ↔ `app/main.py` routes, no stale `BOR_` names, and README/AGENTS claims through phase 194.
|
||||
|
||||
**Notes/deviations** — no live-infra changes (prod sync knob ships default-on, no deployment touched); no git index/history commands run (all changes left in the working tree for the harness); commit criterion left to the harness as instructed.
|
||||
|
||||
**Next pending phase:** none — `.agents/phases/todo/` holds only `194_sync_pending_count`, which is now ready to move to `complete/`.
|
||||
@@ -0,0 +1 @@
|
||||
ok
|
||||
@@ -0,0 +1,151 @@
|
||||
........................................................................ [ 1%]
|
||||
........................................................................ [ 2%]
|
||||
........................................................................ [ 4%]
|
||||
........................................................................ [ 5%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 8%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 13%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 16%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 20%]
|
||||
........................................................................ [ 22%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 26%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 34%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 41%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 44%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 53%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 64%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 67%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 69%]
|
||||
........................................................................ [ 71%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 75%]
|
||||
........................................................................ [ 77%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 90%]
|
||||
........................................................................ [ 92%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 95%]
|
||||
........................................................................ [ 96%]
|
||||
........................................................................ [ 98%]
|
||||
........................................................................ [ 99%]
|
||||
........... [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/admin_settings.py 114 0 100%
|
||||
app/api/auth.py 52 0 100%
|
||||
app/api/chat.py 301 1 99%
|
||||
app/api/chat_images.py 52 0 100%
|
||||
app/api/chats.py 111 0 100%
|
||||
app/api/config.py 13 0 100%
|
||||
app/api/doc_drafts.py 99 0 100%
|
||||
app/api/docs.py 239 1 99%
|
||||
app/api/git_sources.py 259 0 100%
|
||||
app/api/health.py 10 0 100%
|
||||
app/api/source_labels.py 52 0 100%
|
||||
app/api/steering.py 42 0 100%
|
||||
app/api/suggestions.py 33 0 100%
|
||||
app/api/sync.py 242 0 100%
|
||||
app/api/tokens.py 40 0 100%
|
||||
app/api/ui_settings.py 39 0 100%
|
||||
app/config.py 339 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/compression.py 59 0 100%
|
||||
app/core/debugging.py 29 2 93%
|
||||
app/core/docs_push.py 43 0 100%
|
||||
app/core/errors.py 5 0 100%
|
||||
app/core/http_cache.py 22 0 100%
|
||||
app/core/logging.py 13 0 100%
|
||||
app/core/memory.py 32 0 100%
|
||||
app/core/rate_limit.py 44 0 100%
|
||||
app/core/response_budget.py 63 0 100%
|
||||
app/core/security_headers.py 20 0 100%
|
||||
app/core/settings_catalog.py 18 0 100%
|
||||
app/core/settings_migrate.py 32 0 100%
|
||||
app/core/settings_overlay.py 117 0 100%
|
||||
app/core/theming.py 45 0 100%
|
||||
app/core/tokens.py 44 0 100%
|
||||
app/db.py 22 0 100%
|
||||
app/main.py 107 0 100%
|
||||
app/models.py 148 0 100%
|
||||
app/rag/__init__.py 0 0 100%
|
||||
app/rag/agent.py 501 1 99%
|
||||
app/rag/archive_upload.py 134 0 100%
|
||||
app/rag/chunker.py 220 4 98%
|
||||
app/rag/doc_dates.py 18 0 100%
|
||||
app/rag/folder_summaries.py 134 0 100%
|
||||
app/rag/git_sources.py 77 0 100%
|
||||
app/rag/importer.py 906 3 99%
|
||||
app/rag/llm.py 253 1 99%
|
||||
app/rag/md_images.py 63 0 100%
|
||||
app/rag/overview.py 82 0 100%
|
||||
app/rag/pdf.py 192 0 100%
|
||||
app/rag/prompts.py 178 0 100%
|
||||
app/rag/retriever.py 270 3 99%
|
||||
app/rag/scaffolding.py 55 0 100%
|
||||
app/rag/source_labels.py 87 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 58 0 100%
|
||||
app/rag/svg_text.py 111 0 100%
|
||||
app/rag/verbatim.py 160 0 100%
|
||||
app/schemas.py 587 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 7240 16 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
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Task 01 is complete and green.
|
||||
|
||||
**Server-side (phase 194 task 01)**
|
||||
- `app/config.py` — `sync_pending_count: int = 1` (`BOR_SYNC_PENDING_COUNT`), negative refuses startup naming the field; `app/core/settings_catalog.py` — the `Import & sources` row.
|
||||
- `app/rag/importer.py` — new `_pending_hash_stmt` (scalar `SELECT documents.file_hash`, `(source, path)` predicate, no entity/identity-map load) and `_prescan_pending` (per-file `_file_hash` + one scalar read → `{(source, rel): 1-based pending position}`, its own session, `on_scan_progress` per file). `import_sources` gained `on_scan_progress`, reads the switch **once** before the loop, and REPLACES the phase-64 stats pre-walk with ONE `asyncio.to_thread` pre-scan; `progress` now reports the pending position (holds across unchanged files), `0` runs the byte-identical phase-193 walk-position branch, `progress=None` pays nothing. `summary.files`, `seen`, prune, date refresh, log lines untouched.
|
||||
- Docs: `.env.example`, `README.md` (label semantics + a phase-194 bounds bullet + the settings table), `AGENTS.md` (new rule 18).
|
||||
|
||||
**Tests**
|
||||
- New: `tests/unit/test_sync_pending_count.py` (13 — gate both ways, read-once + `to_thread` markers, exactly-`file_hash` projection, 4 predicate states + ignore parity, unreadable arm, scan-hook per root/empty/worker-thread, `done` position, CLI byte-identity) and `tests/integration/test_sync_pending_count.py` (7 — fresh/unchanged/incremental parity `total == added+updated`, 2-file count-down, one-column + `identity_map == 0`, off-loop heartbeat + thread identity, cancel-at-the-await).
|
||||
- Retargeted the two phase-64/129 pair pins in `tests/unit/test_importer.py`; extended `test_config.py` / `test_settings_catalog.py`.
|
||||
|
||||
**Gates**: `ruff check .` clean · `pyright` 0 errors · `pytest --cov=app` **exit 0**, app coverage **99 %** (importer 99 %) · 20 sync/progress E2E suites + smoke green.
|
||||
|
||||
**Deferred by design**: the `scan` status phase / `Scanning…` label (tasks 02–03), the phase's E2E file (task 05). Task 04's pinned suites needed **no** retargeting — they run fresh-import fixtures where the walk *is* the work. Nothing committed (per instructions), no task files touched.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
........................................................................ [ 1%]
|
||||
........................................................................ [ 2%]
|
||||
........................................................................ [ 4%]
|
||||
........................................................................ [ 5%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 8%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 13%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 16%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 20%]
|
||||
........................................................................ [ 22%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 26%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 34%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 41%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 44%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 53%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 64%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 67%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 71%]
|
||||
........................................................................ [ 73%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 77%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 82%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 88%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 92%]
|
||||
........................................................................ [ 94%]
|
||||
........................................................................ [ 95%]
|
||||
........................................................................ [ 97%]
|
||||
........................................................................ [ 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/admin_settings.py 114 0 100%
|
||||
app/api/auth.py 52 0 100%
|
||||
app/api/chat.py 301 1 99%
|
||||
app/api/chat_images.py 52 0 100%
|
||||
app/api/chats.py 111 0 100%
|
||||
app/api/config.py 13 0 100%
|
||||
app/api/doc_drafts.py 99 0 100%
|
||||
app/api/docs.py 239 1 99%
|
||||
app/api/git_sources.py 259 0 100%
|
||||
app/api/health.py 10 0 100%
|
||||
app/api/source_labels.py 52 0 100%
|
||||
app/api/steering.py 42 0 100%
|
||||
app/api/suggestions.py 33 0 100%
|
||||
app/api/sync.py 231 0 100%
|
||||
app/api/tokens.py 40 0 100%
|
||||
app/api/ui_settings.py 39 0 100%
|
||||
app/config.py 339 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/compression.py 59 0 100%
|
||||
app/core/debugging.py 29 2 93%
|
||||
app/core/docs_push.py 43 0 100%
|
||||
app/core/errors.py 5 0 100%
|
||||
app/core/http_cache.py 22 0 100%
|
||||
app/core/logging.py 13 0 100%
|
||||
app/core/memory.py 32 0 100%
|
||||
app/core/rate_limit.py 44 0 100%
|
||||
app/core/response_budget.py 63 0 100%
|
||||
app/core/security_headers.py 20 0 100%
|
||||
app/core/settings_catalog.py 18 0 100%
|
||||
app/core/settings_migrate.py 32 0 100%
|
||||
app/core/settings_overlay.py 117 0 100%
|
||||
app/core/theming.py 45 0 100%
|
||||
app/core/tokens.py 44 0 100%
|
||||
app/db.py 22 0 100%
|
||||
app/main.py 107 0 100%
|
||||
app/models.py 148 0 100%
|
||||
app/rag/__init__.py 0 0 100%
|
||||
app/rag/agent.py 501 1 99%
|
||||
app/rag/archive_upload.py 134 0 100%
|
||||
app/rag/chunker.py 220 4 98%
|
||||
app/rag/doc_dates.py 18 0 100%
|
||||
app/rag/folder_summaries.py 134 0 100%
|
||||
app/rag/git_sources.py 77 0 100%
|
||||
app/rag/importer.py 906 3 99%
|
||||
app/rag/llm.py 253 1 99%
|
||||
app/rag/md_images.py 63 0 100%
|
||||
app/rag/overview.py 82 0 100%
|
||||
app/rag/pdf.py 192 0 100%
|
||||
app/rag/prompts.py 178 0 100%
|
||||
app/rag/retriever.py 270 3 99%
|
||||
app/rag/scaffolding.py 55 0 100%
|
||||
app/rag/source_labels.py 87 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 58 0 100%
|
||||
app/rag/svg_text.py 111 0 100%
|
||||
app/rag/verbatim.py 160 0 100%
|
||||
app/schemas.py 587 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 7229 16 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
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
All gates green. Final state:
|
||||
|
||||
**Implemented (task 02 — D3, the status half)**
|
||||
- `app/api/sync.py`: `SyncStatus.phase` → `Literal["scan","import","overview","summaries"]|None`; new `scan_done`/`scan_total` (after `files_total`, reset with the run, kept at every terminal); `_run_sync` sets `"scan"` immediately before `import_sources` (replacing `= "import"`) with a FORCED `_sample_rss`, adds ONE `_scan_hook` (unforced/throttled sample) passed as `on_scan_progress`, and the `_hook` closure now flips `scan → import` on the first progress call with a forced sample; payload gains `"scan_done"`/`"scan_total"` ADDITIVELY; module / class / endpoint / `_run_sync` docstrings + the `_RSS_SAMPLE_INTERVAL_S` note + the three terminals' keep-final comments updated. Terminals, log lines and every pre-existing key untouched.
|
||||
- New pin suite `tests/integration/test_sync_scan_phase.py` (7): real-run scan frames (≥2 positions, `current_file` null) + both pairs kept at the terminal and **divergent** on the one-changed-file arm (scan 3/3 vs files 1/1, `updated=1`); choreographed flip frame carrying the predicted `files_total`; additive key set idle→mid-run→terminal; forced/throttled sample sequence `null→scan→import→overview→summaries→null` with exactly ONE `/proc` read inside the scan phase; empty-KB arm on both sides; cancel-during-scan terminal (counts kept, nothing indexed, `sync: cancelled by user …` prefix intact); `BOR_SYNC_PENDING_COUNT=0` = `0/0` scan + WALK file count.
|
||||
- Retargeted stale pins (defects my change exposed): `test_sync_api.py` (idle dict + both `_PRE_187_STATUS_KEYS` assertions, `FakeImportSources`/`_GatedImport`/`failing_import` accept `on_scan_progress`, 409-concurrency pin now waits `"scan"` — a canned hook-less import legitimately stays pre-import), `test_sync_git_freeze.py`, `test_sync_button.py` (idle shape, key set, the two sampling pins now count the scan transition: 3 reads start→scan→flip), `test_sync_peak_memory_visible.py` (browser key-set pin + `_COUNT_KEYS`).
|
||||
|
||||
**Gates (exact)**
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → **4822 passed**, TOTAL **99 %**, `app/api/sync.py` **100 % (0 miss)**, exit 0.
|
||||
- `uv run ruff check .` → All checks passed · `uv run pyright` → 0 errors.
|
||||
- E2E regression (30 modules, all passed): `test_sync_remaining_count`, `test_sync_button`, `test_sync_progress_box`, `test_sync_label_mobile`, `test_sync_cancel`, `test_sync_status_freshness`, `test_sync_peak_memory_visible`, `test_sync_chunk_progress`, `test_sync_upload_progress`, `test_archive_upload_sources`, `test_sync_summary_visibility`, `test_sync_image_progress`, `test_sync_changed_only`, `test_sync_session_reset`, `test_fast_path_deferred_content`, `test_sync_model_down`, `test_sync_git_freeze`, `test_force_push_resync`, `test_source_name_labels`, `test_local_directory_sources`, `test_source_ignore_paths`, `test_folder_summary_voice`, `test_incremental_folder_summaries`, `test_upload_no_scan`, `test_git_source_branch`, `test_hidden_folders_toggle`, `test_prune_cascade_cleanup`, `test_git_log_stream_dates`, `test_kb_tree`, `test_smoke`.
|
||||
|
||||
**Docs**: README (`phase` machine + additive `scan_done`/`scan_total` clause; the phase-187 sampling bullet now lists `scan → import → overview → summaries`) and `AGENTS.md` rule 18 (status half: machine, flip-in-`_hook` rule, additive chain, forced-vs-throttled sampling, degenerate edge, new pinned suites). No new env var; nothing committed (harness commits).
|
||||
|
||||
**Notes/deviations**: D3 kept exactly (the flip lives in the existing per-file hook, no extra importer callback), so a canned import that fires no hook stays in `"scan"` — that is why the pre-existing 409 pin retargets. The real-run arm pins terminal values instead of an `"import"` frame because an in-process import never yields the loop (documented in the test module docstring); the flip frame gets a deterministic choreographed pin. `Scanning…` label copy intentionally left to task 03.
|
||||
|
||||
**Next pending task**: `.agents/phases/todo/194_sync_pending_count/03_ui_scan_label.md` (`fmtSyncPhaseLabel` scan branch).
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
........................................................................ [ 1%]
|
||||
........................................................................ [ 2%]
|
||||
........................................................................ [ 4%]
|
||||
........................................................................ [ 5%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 8%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 13%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 16%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 20%]
|
||||
........................................................................ [ 22%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 26%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 34%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 41%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 44%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 53%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 64%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 67%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 71%]
|
||||
........................................................................ [ 73%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 76%]
|
||||
........................................................................ [ 77%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 82%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 88%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 92%]
|
||||
........................................................................ [ 94%]
|
||||
........................................................................ [ 95%]
|
||||
........................................................................ [ 97%]
|
||||
........................................................................ [ 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/admin_settings.py 114 0 100%
|
||||
app/api/auth.py 52 0 100%
|
||||
app/api/chat.py 301 1 99%
|
||||
app/api/chat_images.py 52 0 100%
|
||||
app/api/chats.py 111 0 100%
|
||||
app/api/config.py 13 0 100%
|
||||
app/api/doc_drafts.py 99 0 100%
|
||||
app/api/docs.py 239 1 99%
|
||||
app/api/git_sources.py 259 0 100%
|
||||
app/api/health.py 10 0 100%
|
||||
app/api/source_labels.py 52 0 100%
|
||||
app/api/steering.py 42 0 100%
|
||||
app/api/suggestions.py 33 0 100%
|
||||
app/api/sync.py 242 0 100%
|
||||
app/api/tokens.py 40 0 100%
|
||||
app/api/ui_settings.py 39 0 100%
|
||||
app/config.py 339 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/compression.py 59 0 100%
|
||||
app/core/debugging.py 29 2 93%
|
||||
app/core/docs_push.py 43 0 100%
|
||||
app/core/errors.py 5 0 100%
|
||||
app/core/http_cache.py 22 0 100%
|
||||
app/core/logging.py 13 0 100%
|
||||
app/core/memory.py 32 0 100%
|
||||
app/core/rate_limit.py 44 0 100%
|
||||
app/core/response_budget.py 63 0 100%
|
||||
app/core/security_headers.py 20 0 100%
|
||||
app/core/settings_catalog.py 18 0 100%
|
||||
app/core/settings_migrate.py 32 0 100%
|
||||
app/core/settings_overlay.py 117 0 100%
|
||||
app/core/theming.py 45 0 100%
|
||||
app/core/tokens.py 44 0 100%
|
||||
app/db.py 22 0 100%
|
||||
app/main.py 107 0 100%
|
||||
app/models.py 148 0 100%
|
||||
app/rag/__init__.py 0 0 100%
|
||||
app/rag/agent.py 501 1 99%
|
||||
app/rag/archive_upload.py 134 0 100%
|
||||
app/rag/chunker.py 220 4 98%
|
||||
app/rag/doc_dates.py 18 0 100%
|
||||
app/rag/folder_summaries.py 134 0 100%
|
||||
app/rag/git_sources.py 77 0 100%
|
||||
app/rag/importer.py 906 3 99%
|
||||
app/rag/llm.py 253 1 99%
|
||||
app/rag/md_images.py 63 0 100%
|
||||
app/rag/overview.py 82 0 100%
|
||||
app/rag/pdf.py 192 0 100%
|
||||
app/rag/prompts.py 178 0 100%
|
||||
app/rag/retriever.py 270 3 99%
|
||||
app/rag/scaffolding.py 55 0 100%
|
||||
app/rag/source_labels.py 87 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 58 0 100%
|
||||
app/rag/svg_text.py 111 0 100%
|
||||
app/rag/verbatim.py 160 0 100%
|
||||
app/schemas.py 587 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 7240 16 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,17 @@
|
||||
All gates green. Final state:
|
||||
|
||||
**Implemented (task 03 — D4, the UI half)**
|
||||
- `frontend/assets/sources.js`: `fmtSyncPhaseLabel` gains ONE `"scan"` branch as its **first** arm — main `Scanning…` (never a file; the branch never reads `current_file`) + count `(scan_done/scan_total)` in the SAME count slot the import `N remaining` uses, with the phase-64 `scan_total > 0` guard (0/0 → bare `Scanning…`) and `chunk`/`image` empty; `fmtSyncLabel`'s `N remaining` arithmetic, the chunk/image/summaries builders, `setSyncLabel`, `fmtSyncResult`, `fmtSyncPeakClause` untouched (whole-status pass-through at both call sites already carries the scan pair — comments + docstrings now name it); module header, phase-98 header, the section decision tree and the wrapper docstring updated (fallback narrowed to the null prelude + `import`, TODO L6 honesty clause added).
|
||||
- New pin suite `tests/unit/test_sync_scan_label_ui.py` (13): branch order, the exact `(n/total)` shape + guard, no-file/no-other-pair reads, the tick + re-attach pass-through, the untouched builder/writer set, docstring/header markers, plus a **node run of the real label path** (`Scanning… (3/9)` identical on main/count/title/box/aria; bare `Scanning…` at `0/0`; every other phase byte-identical).
|
||||
- No server-side change (tasks 01/02 already shipped the phase + payload keys).
|
||||
|
||||
**Gates (exact)**
|
||||
- `uv run pytest --cov=app --cov-report=term` → **4835 passed**, TOTAL **99 %** (`app/api/sync.py` 100 %), exit 0.
|
||||
- `uv run ruff check .` → All checks passed · `uv run pyright` → 0 errors · `node --check sources.js` → OK.
|
||||
- E2E regression (32 modules, all passed, none edited): `test_sync_remaining_count` (phase-193 pins byte-identical), `test_sync_progress_box`, `test_sync_label_mobile`, `test_sync_chunk_progress`, `test_sync_summary_visibility`, `test_sync_image_progress`, `test_sync_status_freshness`, `test_sync_button`, `test_sync_cancel`, `test_sync_peak_memory_visible`, `test_sync_upload_progress`, `test_upload_no_scan`, `test_archive_upload_sources`, `test_sync_model_down`, `test_sync_changed_only`, `test_sync_session_reset`, `test_sync_git_freeze`, `test_fast_path_deferred_content`, `test_force_push_resync`, `test_prune_cascade_cleanup`, `test_local_directory_sources`, `test_source_ignore_paths`, `test_hidden_folders_toggle`, `test_kb_tree`, `test_git_source_branch`, `test_git_log_stream_dates`, `test_source_name_labels`, `test_folder_summary_voice`, `test_incremental_folder_summaries`, `test_answer_images`, `test_pdf_support`, `test_smoke`.
|
||||
|
||||
**Docs**: README (the running-label bullet now leads with `"Scanning… (n/total)"`, the phase-194 bullet names the branch + its A4 placement) and `AGENTS.md` rule 18 (new "UI half" clause: first-arm rule, no-file/no-chunk-image, `total === 0` bare label, honesty rule, whole-status pass-through, untouched set, the new pin module).
|
||||
|
||||
**Notes/deviations**: the `(n/total)` branch is placed before `overview`/`summaries` so every pre-existing branch slice in the phase-128/152 pins stays byte-identical; the D4 "caller pass-through" needed no argument-list change (the whole `status` object is already the 5th arg — the same carrier as the summaries/chunk/image pairs), so it is pinned + documented rather than re-listed. No pinned E2E suite went stale under this change, so nothing was retargeted here (task 04 stays as authored).
|
||||
|
||||
**Next pending task**: `.agents/phases/todo/194_sync_pending_count/04_retarget_pinned_suites.md`.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
........................................................................ [ 1%]
|
||||
........................................................................ [ 2%]
|
||||
........................................................................ [ 4%]
|
||||
........................................................................ [ 5%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 8%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 13%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 16%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 20%]
|
||||
........................................................................ [ 22%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 26%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 34%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 41%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 44%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 53%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 64%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 67%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 69%]
|
||||
........................................................................ [ 71%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 75%]
|
||||
........................................................................ [ 77%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 90%]
|
||||
........................................................................ [ 92%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 95%]
|
||||
........................................................................ [ 96%]
|
||||
........................................................................ [ 98%]
|
||||
........................................................................ [ 99%]
|
||||
........... [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/admin_settings.py 114 0 100%
|
||||
app/api/auth.py 52 0 100%
|
||||
app/api/chat.py 301 1 99%
|
||||
app/api/chat_images.py 52 0 100%
|
||||
app/api/chats.py 111 0 100%
|
||||
app/api/config.py 13 0 100%
|
||||
app/api/doc_drafts.py 99 0 100%
|
||||
app/api/docs.py 239 1 99%
|
||||
app/api/git_sources.py 259 0 100%
|
||||
app/api/health.py 10 0 100%
|
||||
app/api/source_labels.py 52 0 100%
|
||||
app/api/steering.py 42 0 100%
|
||||
app/api/suggestions.py 33 0 100%
|
||||
app/api/sync.py 242 0 100%
|
||||
app/api/tokens.py 40 0 100%
|
||||
app/api/ui_settings.py 39 0 100%
|
||||
app/config.py 339 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/compression.py 59 0 100%
|
||||
app/core/debugging.py 29 2 93%
|
||||
app/core/docs_push.py 43 0 100%
|
||||
app/core/errors.py 5 0 100%
|
||||
app/core/http_cache.py 22 0 100%
|
||||
app/core/logging.py 13 0 100%
|
||||
app/core/memory.py 32 0 100%
|
||||
app/core/rate_limit.py 44 0 100%
|
||||
app/core/response_budget.py 63 0 100%
|
||||
app/core/security_headers.py 20 0 100%
|
||||
app/core/settings_catalog.py 18 0 100%
|
||||
app/core/settings_migrate.py 32 0 100%
|
||||
app/core/settings_overlay.py 117 0 100%
|
||||
app/core/theming.py 45 0 100%
|
||||
app/core/tokens.py 44 0 100%
|
||||
app/db.py 22 0 100%
|
||||
app/main.py 107 0 100%
|
||||
app/models.py 148 0 100%
|
||||
app/rag/__init__.py 0 0 100%
|
||||
app/rag/agent.py 501 1 99%
|
||||
app/rag/archive_upload.py 134 0 100%
|
||||
app/rag/chunker.py 220 4 98%
|
||||
app/rag/doc_dates.py 18 0 100%
|
||||
app/rag/folder_summaries.py 134 0 100%
|
||||
app/rag/git_sources.py 77 0 100%
|
||||
app/rag/importer.py 906 3 99%
|
||||
app/rag/llm.py 253 1 99%
|
||||
app/rag/md_images.py 63 0 100%
|
||||
app/rag/overview.py 82 0 100%
|
||||
app/rag/pdf.py 192 0 100%
|
||||
app/rag/prompts.py 178 0 100%
|
||||
app/rag/retriever.py 270 3 99%
|
||||
app/rag/scaffolding.py 55 0 100%
|
||||
app/rag/source_labels.py 87 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 58 0 100%
|
||||
app/rag/svg_text.py 111 0 100%
|
||||
app/rag/verbatim.py 160 0 100%
|
||||
app/schemas.py 587 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 7240 16 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 @@
|
||||
Everything is green. Final verification summary:
|
||||
|
||||
**Implemented (task 04 — the D5 pinned-suite retarget)**
|
||||
- `tests/e2e/test_sync_remaining_count.py` (phase 193's own suite) retargeted: docstring's "Server untouched / phase-64 key set / walk position" clauses now state the pending-set semantics (the phase-193 walk wording kept as the `BOR_SYNC_PENDING_COUNT=0` history); new `EXPECTED_STATUS_KEYS` additive key-set pin (phase-64 set + memory pair + `scan_done`/`scan_total`) asserted on every real tick AND on the served stub; new `_assert_phase_machine_tick_series()` pins the `"scan"` stage (file-less scan ticks carrying `scan_total`, `0/0` null prelude, one-directional sequence, terminal keeping BOTH pairs, `files_total ≤ scan_total`); test 2's pre-first-file region now renders/serves `Scanning… (2/5)`, the bare `Scanning…` (`scan_total===0`) and the null prelude; **new test 4** syncs the same repo twice — run 2's wire pair is `0/0` (empty pending set) while `scan_done == scan_total == 5` is kept at the terminal, terminal line `0 added · 5 unchanged` byte-identical, no count part rendered. `_TickRecorder` gained `wait_for_running` (+ `started_at` ownership) — a recorder started on a previous run's terminal was silently handing that body back (the bug test 4 exposed).
|
||||
- Verified green **UNEDITED** (pins untouched): upload arm (test 3), `test_sync_chunk_progress`, `test_sync_label_mobile`, `test_sync_upload_progress`, `test_archive_upload_sources`, `test_sync_session_reset`, `test_fast_path_deferred_content`, `test_sync_summary_visibility`, `test_sync_image_progress`, `test_sync_progress_box`, `test_sync_status_freshness`, `test_sync_peak_memory_visible`, `test_smoke`; phase-185 `-230`→`-228` per-file SELECT pins and phase-184 retention bound unaffected (the pre-scan reads a scalar projection through its own session). Docstring-only notes recorded that inspection in `test_sync_chunk_progress.py`, `test_sync_progress_box.py`, `test_import_fast_path_columns.py`, `test_import_session_retention.py`, `test_sync_git_freeze.py` (whose stubbed import means the pre-scan never enters its measurement window — the span's own off-loop/cancel pins live in `test_sync_pending_count.py`).
|
||||
- No app, README or AGENTS change (item 9: task 05 owns the docs).
|
||||
|
||||
**Gates (exact)**
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → **4835 passed**, TOTAL **99 %** (`app/api/sync.py` 100 %, `app/config.py` 100 %, `app/rag/importer.py` 99 %), exit 0.
|
||||
- `uv run ruff check .` → All checks passed · `uv run pyright` → **0 errors** · `node --check frontend/assets/sources.js` → OK.
|
||||
- Isolated `--no-cov` sweep, items 1/5–8: 13/13 PASS (`test_sync_remaining_count` 97 s with 4 tests). Adjacent sync-lineage batch: 12/12 PASS (`test_sync_button`, `_cancel`, `test_upload_no_scan`, `_changed_only`, `_model_down`, `test_force_push_resync`, `test_prune_cascade_cleanup`, `test_git_log_stream_dates`, `test_folder_summary_voice`, `test_incremental_folder_summaries`, `test_local_directory_sources`, `test_source_ignore_paths`). Items 2–4 integration files re-run isolated: PASS.
|
||||
|
||||
**Notable decisions / notes**
|
||||
- Real-run `phase:"scan"` frames are not observable on a 5-file fixture (single-digit-ms window vs a 100 ms poll), so the real arm pins the machine's *deterministic evidence* while the deterministic `Scanning… (n/total)` frames ride test 2's served statuses and the choreographed server sequence stays in `tests/integration/test_sync_scan_phase.py` (documented in the module docstring).
|
||||
- One pin deliberately relaxed with a reason: the prelude `0/0` arm is skipped for run 2 (`prelude_zero=False`) because `_run_sync` sets `state="running"` one synchronous statement before resetting the scan pair while `GET /api/sync/status` answers from a threadpool — a pre-existing (phase-64) reset shape, not changed here.
|
||||
- Two integration suites failed transiently when I ran them concurrently with an E2E batch (shared Postgres + per-test `TRUNCATE`); re-run in isolation they pass — E2E and integration must not overlap on this DB. Three orphaned uvicorns on ports 8997–8999 belong to another session's `dev` container; left untouched.
|
||||
|
||||
**Next pending task**: `.agents/phases/todo/194_sync_pending_count/05_e2e_and_gates.md` (the phase's own `tests/e2e/test_sync_pending_count.py`, the docs pass, the atomic commit).
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
........................................................................ [ 1%]
|
||||
........................................................................ [ 2%]
|
||||
........................................................................ [ 4%]
|
||||
........................................................................ [ 5%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 8%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 13%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 16%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 20%]
|
||||
........................................................................ [ 22%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 26%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 34%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 41%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 44%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 53%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 64%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 67%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 69%]
|
||||
........................................................................ [ 71%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 75%]
|
||||
........................................................................ [ 77%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 90%]
|
||||
........................................................................ [ 92%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 95%]
|
||||
........................................................................ [ 96%]
|
||||
........................................................................ [ 98%]
|
||||
........................................................................ [ 99%]
|
||||
........... [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/admin_settings.py 114 0 100%
|
||||
app/api/auth.py 52 0 100%
|
||||
app/api/chat.py 301 1 99%
|
||||
app/api/chat_images.py 52 0 100%
|
||||
app/api/chats.py 111 0 100%
|
||||
app/api/config.py 13 0 100%
|
||||
app/api/doc_drafts.py 99 0 100%
|
||||
app/api/docs.py 239 1 99%
|
||||
app/api/git_sources.py 259 0 100%
|
||||
app/api/health.py 10 0 100%
|
||||
app/api/source_labels.py 52 0 100%
|
||||
app/api/steering.py 42 0 100%
|
||||
app/api/suggestions.py 33 0 100%
|
||||
app/api/sync.py 242 0 100%
|
||||
app/api/tokens.py 40 0 100%
|
||||
app/api/ui_settings.py 39 0 100%
|
||||
app/config.py 339 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/compression.py 59 0 100%
|
||||
app/core/debugging.py 29 2 93%
|
||||
app/core/docs_push.py 43 0 100%
|
||||
app/core/errors.py 5 0 100%
|
||||
app/core/http_cache.py 22 0 100%
|
||||
app/core/logging.py 13 0 100%
|
||||
app/core/memory.py 32 0 100%
|
||||
app/core/rate_limit.py 44 0 100%
|
||||
app/core/response_budget.py 63 0 100%
|
||||
app/core/security_headers.py 20 0 100%
|
||||
app/core/settings_catalog.py 18 0 100%
|
||||
app/core/settings_migrate.py 32 0 100%
|
||||
app/core/settings_overlay.py 117 0 100%
|
||||
app/core/theming.py 45 0 100%
|
||||
app/core/tokens.py 44 0 100%
|
||||
app/db.py 22 0 100%
|
||||
app/main.py 107 0 100%
|
||||
app/models.py 148 0 100%
|
||||
app/rag/__init__.py 0 0 100%
|
||||
app/rag/agent.py 501 1 99%
|
||||
app/rag/archive_upload.py 134 0 100%
|
||||
app/rag/chunker.py 220 4 98%
|
||||
app/rag/doc_dates.py 18 0 100%
|
||||
app/rag/folder_summaries.py 134 0 100%
|
||||
app/rag/git_sources.py 77 0 100%
|
||||
app/rag/importer.py 906 3 99%
|
||||
app/rag/llm.py 253 1 99%
|
||||
app/rag/md_images.py 63 0 100%
|
||||
app/rag/overview.py 82 0 100%
|
||||
app/rag/pdf.py 192 0 100%
|
||||
app/rag/prompts.py 178 0 100%
|
||||
app/rag/retriever.py 270 3 99%
|
||||
app/rag/scaffolding.py 55 0 100%
|
||||
app/rag/source_labels.py 87 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 58 0 100%
|
||||
app/rag/svg_text.py 111 0 100%
|
||||
app/rag/verbatim.py 160 0 100%
|
||||
app/schemas.py 587 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 7240 16 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,15 @@
|
||||
**Phase 194 / task 05 — complete.**
|
||||
|
||||
`tests/e2e/test_sync_pending_count.py` (new, 1,999 lines, 8 arms, own ports 8212/8213 + slow-proxy 8915, two live module apps over the `file://` git transport and a delay-injecting mock model):
|
||||
1. fresh KB — `null → scan → import → terminal`, scan pair completes and survives the terminal, `N remaining` = phase-193 walk arithmetic (pending == walk), real-run peak clause == payload `rss_peak_mb`;
|
||||
2. incremental (8 indexed, 2 changed) — `files_total == 2` every running tick, count **holds** at `2 remaining` while `current_file` names unchanged files, absent on the final predicted file;
|
||||
3. exact scan/null/hold payloads served to the real `sources.js` — `Scanning… (n/total)` on main/count/title/`#sync-progress` only, one `aria-live` box, no `N remaining`/file/chunk in the scan arm, no peak clause on any running label, terminal `0 added · 2 updated · 6 unchanged · peak 1234 MB`;
|
||||
4. `BOR_SYNC_PENDING_COUNT=0` app on the same fixture — `"7 remaining"` (1 predicted), no `scan` phase, payload carries `scan_done/scan_total` at `0/0`;
|
||||
5. no-change re-sync — `files_total == 0` on every tick, no count part anywhere, machine still clean;
|
||||
6. empty source — scan reached, import never, bare `Scanning…`, terminal `0 added · 0 unchanged`;
|
||||
7. prod-shaped 1,000-file KB — scan position caught **climbing through the running server** (`scan_total == 1000`, `current_file` null), every import tick at `2`, no tick and no label ever walk-sized;
|
||||
8. upload — bare phase-64 key set (no `phase`/`scan_*`/chunk/image/summary/memory keys), bare label.
|
||||
|
||||
Docs: added the browser pin to the README phase-194 bullet and AGENTS.md rule 18 (incl. the terminal-only peak-clause reading of task 05's wording). `.env.example`/README settings row already correct — no other inconsistency found.
|
||||
|
||||
Gates: `pytest tests/e2e/test_sync_pending_count.py -v --no-cov` → **8 passed in 146.8s**; sync-lineage sweep of all 15 E2E suites in isolation → **15/15 exit 0**; full `pytest --cov=app` → **exit 0, app coverage 99%** (>90%); `ruff check .` → all checks passed; `pyright` → **0 errors**. No app defect surfaced this task; no git index/history touched.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
........................................................................ [ 1%]
|
||||
........................................................................ [ 2%]
|
||||
........................................................................ [ 4%]
|
||||
........................................................................ [ 5%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 8%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 13%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 16%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 20%]
|
||||
........................................................................ [ 22%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 25%]
|
||||
........................................................................ [ 26%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 29%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 32%]
|
||||
........................................................................ [ 34%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 40%]
|
||||
........................................................................ [ 41%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 44%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 47%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 53%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 64%]
|
||||
........................................................................ [ 65%]
|
||||
........................................................................ [ 67%]
|
||||
........................................................................ [ 68%]
|
||||
........................................................................ [ 69%]
|
||||
........................................................................ [ 71%]
|
||||
........................................................................ [ 72%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 75%]
|
||||
........................................................................ [ 77%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 83%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 86%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 90%]
|
||||
........................................................................ [ 92%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 95%]
|
||||
........................................................................ [ 96%]
|
||||
........................................................................ [ 98%]
|
||||
........................................................................ [ 99%]
|
||||
........... [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/admin_settings.py 114 0 100%
|
||||
app/api/auth.py 52 0 100%
|
||||
app/api/chat.py 301 1 99%
|
||||
app/api/chat_images.py 52 0 100%
|
||||
app/api/chats.py 111 0 100%
|
||||
app/api/config.py 13 0 100%
|
||||
app/api/doc_drafts.py 99 0 100%
|
||||
app/api/docs.py 239 1 99%
|
||||
app/api/git_sources.py 259 0 100%
|
||||
app/api/health.py 10 0 100%
|
||||
app/api/source_labels.py 52 0 100%
|
||||
app/api/steering.py 42 0 100%
|
||||
app/api/suggestions.py 33 0 100%
|
||||
app/api/sync.py 242 0 100%
|
||||
app/api/tokens.py 40 0 100%
|
||||
app/api/ui_settings.py 39 0 100%
|
||||
app/config.py 339 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/compression.py 59 0 100%
|
||||
app/core/debugging.py 29 2 93%
|
||||
app/core/docs_push.py 43 0 100%
|
||||
app/core/errors.py 5 0 100%
|
||||
app/core/http_cache.py 22 0 100%
|
||||
app/core/logging.py 13 0 100%
|
||||
app/core/memory.py 32 0 100%
|
||||
app/core/rate_limit.py 44 0 100%
|
||||
app/core/response_budget.py 63 0 100%
|
||||
app/core/security_headers.py 20 0 100%
|
||||
app/core/settings_catalog.py 18 0 100%
|
||||
app/core/settings_migrate.py 32 0 100%
|
||||
app/core/settings_overlay.py 117 0 100%
|
||||
app/core/theming.py 45 0 100%
|
||||
app/core/tokens.py 44 0 100%
|
||||
app/db.py 22 0 100%
|
||||
app/main.py 107 0 100%
|
||||
app/models.py 148 0 100%
|
||||
app/rag/__init__.py 0 0 100%
|
||||
app/rag/agent.py 501 1 99%
|
||||
app/rag/archive_upload.py 134 0 100%
|
||||
app/rag/chunker.py 220 4 98%
|
||||
app/rag/doc_dates.py 18 0 100%
|
||||
app/rag/folder_summaries.py 134 0 100%
|
||||
app/rag/git_sources.py 77 0 100%
|
||||
app/rag/importer.py 906 3 99%
|
||||
app/rag/llm.py 253 1 99%
|
||||
app/rag/md_images.py 63 0 100%
|
||||
app/rag/overview.py 82 0 100%
|
||||
app/rag/pdf.py 192 0 100%
|
||||
app/rag/prompts.py 178 0 100%
|
||||
app/rag/retriever.py 270 3 99%
|
||||
app/rag/scaffolding.py 55 0 100%
|
||||
app/rag/source_labels.py 87 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 58 0 100%
|
||||
app/rag/svg_text.py 111 0 100%
|
||||
app/rag/verbatim.py 160 0 100%
|
||||
app/schemas.py 587 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 7240 16 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