diff --git a/.agents/phases/todo/149_sync_progress_box/00_phase.md b/.agents/phases/complete/149_sync_progress_box/00_phase.md
similarity index 100%
rename from .agents/phases/todo/149_sync_progress_box/00_phase.md
rename to .agents/phases/complete/149_sync_progress_box/00_phase.md
diff --git a/.agents/phases/todo/149_sync_progress_box/01_progress_box_wiring.md b/.agents/phases/complete/149_sync_progress_box/01_progress_box_wiring.md
similarity index 100%
rename from .agents/phases/todo/149_sync_progress_box/01_progress_box_wiring.md
rename to .agents/phases/complete/149_sync_progress_box/01_progress_box_wiring.md
diff --git a/.agents/phases/todo/149_sync_progress_box/02_progress_box_styles.md b/.agents/phases/complete/149_sync_progress_box/02_progress_box_styles.md
similarity index 100%
rename from .agents/phases/todo/149_sync_progress_box/02_progress_box_styles.md
rename to .agents/phases/complete/149_sync_progress_box/02_progress_box_styles.md
diff --git a/.agents/phases/todo/149_sync_progress_box/03_e2e_progress_box.md b/.agents/phases/complete/149_sync_progress_box/03_e2e_progress_box.md
similarity index 100%
rename from .agents/phases/todo/149_sync_progress_box/03_e2e_progress_box.md
rename to .agents/phases/complete/149_sync_progress_box/03_e2e_progress_box.md
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.err b/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.err
new file mode 100644
index 0000000..e69de29
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.md b/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.md
new file mode 100644
index 0000000..f0383f9
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.md
@@ -0,0 +1,13 @@
+All verification complete. The `ink-soft`/`--surface` pair the box uses is already pinned AA by the existing theme E2E suites (8.2:1 dark, ~6.9:1 light). Everything is green — no fixes were needed.
+
+**Phase 149 final verification report**
+
+- Verified (no re-work needed): `#sync-progress` box wiring (single `setSyncLabel` writer with `running` flag; `is-running` class travels with the spin; aria-label owned by the writer), the panel/icon-only-button CSS, and the 5-test dedicated E2E; all 6 pre-existing sync E2Es' running pins migrated to the box, settled pins untouched.
+- Dedicated E2E: `uv run pytest tests/e2e/test_sync_progress_box.py -v --no-cov` → **5 passed in 198.6 s** (isolation, slow-proxy mock; under the 600 s budget).
+- Full suite: `uv run pytest --cov=app --cov-report=term-missing` → **3463 passed, app/ coverage 99%** (>90% gate).
+- Migrated sync E2Es, each in isolation: `test_sync_button` 3 passed, `test_sync_cancel` 3, `test_sync_chunk_progress` 2, `test_sync_label_mobile` 4, `test_sync_summary_visibility` 3, `test_sync_upload_progress` 4 — all green.
+- Lint/types: `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors.
+- Criteria: in-flight spinner-only button + full untruncated wrapped box (desktop & mobile 390×844, `scrollWidth ≤ clientWidth`) ✓; settle byte-identical ("Synced HH:MM" + `3 added`, box hidden, aria restored) ✓; `#sync-result` sole live region (box `aria-hidden`), mid-run reload re-attaches ✓; WCAG (AA contrast both themes via the pinned ink-soft/surface pair, focus-visible, reduced-motion kill intact at styles.css L2201) ✓; cancel/409/error/upload/status API unchanged (green suites above) ✓.
+- Documentation: README.md reviewed in full (sync-states paragraph now matches the shipped UI; env-var table matches `app/config.py` and covers all `.env.example` vars; pages/commands verified) and AGENTS.md reviewed in full — **verified consistent, no changes needed**.
+- Notable: no defects found in this or prior work; no live infrastructure touched.
+- Next pending phase: none — `todo/` will be empty once the harness moves 149 (only 149 was pending).
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.validate b/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.validate
new file mode 100644
index 0000000..71a2985
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__00_phase.a1.validate
@@ -0,0 +1,120 @@
+........................................................................ [ 2%]
+........................................................................ [ 4%]
+........................................................................ [ 6%]
+........................................................................ [ 8%]
+........................................................................ [ 10%]
+........................................................................ [ 12%]
+........................................................................ [ 14%]
+........................................................................ [ 16%]
+........................................................................ [ 18%]
+........................................................................ [ 20%]
+........................................................................ [ 22%]
+........................................................................ [ 24%]
+........................................................................ [ 27%]
+........................................................................ [ 29%]
+........................................................................ [ 31%]
+........................................................................ [ 33%]
+........................................................................ [ 35%]
+........................................................................ [ 37%]
+........................................................................ [ 39%]
+........................................................................ [ 41%]
+........................................................................ [ 43%]
+........................................................................ [ 45%]
+........................................................................ [ 47%]
+........................................................................ [ 49%]
+........................................................................ [ 51%]
+........................................................................ [ 54%]
+........................................................................ [ 56%]
+........................................................................ [ 58%]
+........................................................................ [ 60%]
+........................................................................ [ 62%]
+........................................................................ [ 64%]
+........................................................................ [ 66%]
+........................................................................ [ 68%]
+........................................................................ [ 70%]
+........................................................................ [ 72%]
+........................................................................ [ 74%]
+........................................................................ [ 76%]
+........................................................................ [ 79%]
+........................................................................ [ 81%]
+........................................................................ [ 83%]
+........................................................................ [ 85%]
+........................................................................ [ 87%]
+........................................................................ [ 89%]
+........................................................................ [ 91%]
+........................................................................ [ 93%]
+........................................................................ [ 95%]
+........................................................................ [ 97%]
+........................................................................ [ 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/auth.py 52 0 100%
+app/api/chat.py 270 1 99%
+app/api/chat_images.py 50 0 100%
+app/api/chats.py 110 0 100%
+app/api/config.py 13 0 100%
+app/api/doc_drafts.py 99 0 100%
+app/api/docs.py 196 1 99%
+app/api/git_sources.py 259 0 100%
+app/api/health.py 10 0 100%
+app/api/steering.py 42 0 100%
+app/api/suggestions.py 33 0 100%
+app/api/sync.py 183 0 100%
+app/api/tokens.py 40 0 100%
+app/api/ui_settings.py 55 0 100%
+app/config.py 265 0 100%
+app/core/__init__.py 0 0 100%
+app/core/auth.py 45 0 100%
+app/core/caching.py 124 0 100%
+app/core/debugging.py 29 2 93%
+app/core/docs_push.py 39 0 100%
+app/core/errors.py 5 0 100%
+app/core/logging.py 13 0 100%
+app/core/rate_limit.py 44 0 100%
+app/core/security_headers.py 20 0 100%
+app/core/theming.py 38 0 100%
+app/core/tokens.py 44 0 100%
+app/db.py 22 0 100%
+app/main.py 68 0 100%
+app/models.py 135 0 100%
+app/rag/__init__.py 0 0 100%
+app/rag/agent.py 431 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 744 4 99%
+app/rag/llm.py 246 1 99%
+app/rag/md_images.py 63 0 100%
+app/rag/overview.py 71 0 100%
+app/rag/pdf.py 124 0 100%
+app/rag/prompts.py 155 0 100%
+app/rag/retriever.py 248 3 99%
+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 58 0 100%
+app/schemas.py 443 0 100%
+--------------------------------------------------
+TOTAL 5609 17 99%
+coverage gate: app/ 99% (>90%) OK
+All checks passed!
+0 errors, 0 warnings, 0 informations
+WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414).
+Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
+
+validation OK
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.err b/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.err
new file mode 100644
index 0000000..e69de29
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.md b/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.md
new file mode 100644
index 0000000..4e65404
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.md
@@ -0,0 +1,15 @@
+Everything is verified and green. Task 01 is complete.
+
+**Report — Phase 149, Task 01 (`01_progress_box_wiring.md`)**
+
+- **HTML:** `#sync-progress` box (`.sync-progress-text` span) inserted between the `.page-head` block and `#sync-result` — ship-hidden, `aria-hidden` (presentational; `#sync-result` stays the sole aria-live announcer).
+- **sources.js (single-writer wiring):** `setSyncLabel` gains `running=false` — writes the SAME full untruncated label into the box, reveals it IFF a run is in flight, and owns the button's `aria-label` (full live label while running, `"Sync sources"` restored on every settle). `enterSyncRunningState` passes `running=true` + adds `is-running` (with the spin, its old aria write removed); `settleSyncButton` removes `is-running` (with the spin). Covers all 5 running entries (poll ticks, 202/409 click, both re-attaches) and every settle.
+- **Unit tests:** pins moved to the new shape + new HTML markup pin + node-harness rows gain box text/hidden, `is-running`/`is-spinning`, aria-label, with a new behavioral test (box visible IFF running, exact full label, restored at settle).
+- **E2E migration (six sync suites):** running-state label pins → `#sync-progress` (regexes target `#sync-progress-text` — the div's innerText carries newline artifacts); count `to_be_visible` → box visibility; `test_sync_label_mobile` tests 1–3 reworked box-based (full string + viewport-fit + `is-running`), `_settle` gains the box-hidden pin; all settled/idle + `#sync-result` pins untouched.
+- **Docs:** README "States" bullet updated (button = spinner, detail box under the row); no AGENTS.md impact.
+
+**Results:** `uv run pytest --cov=app` → **3463 passed, 99% coverage** (gate >90%); `uv run ruff check .` clean; `uv run pyright` 0 errors; all 11 sync-related E2E files green in isolation (`--no-cov`), incl. the six migrated suites.
+
+**Notable:** (1) `test_sync_label_mobile.py` test 4 (pre-phase-128 CSS clip reproduction) stays green now, but task 02's `.sync-btn.is-running .sync-label{display:none}` (higher specificity) will make the injected rules lose — task 02 must migrate/drop it. (2) Owner appended 2 new TODO.md items mid-session (image-embed sync status) — untouched; likely a future phase.
+
+**Next pending task:** `02_progress_box_styles.md` (box panel CSS, icon-only running button, mobile, AA/motion gates).
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.validate b/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.validate
new file mode 100644
index 0000000..71a2985
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__01_progress_box_wiring.a1.validate
@@ -0,0 +1,120 @@
+........................................................................ [ 2%]
+........................................................................ [ 4%]
+........................................................................ [ 6%]
+........................................................................ [ 8%]
+........................................................................ [ 10%]
+........................................................................ [ 12%]
+........................................................................ [ 14%]
+........................................................................ [ 16%]
+........................................................................ [ 18%]
+........................................................................ [ 20%]
+........................................................................ [ 22%]
+........................................................................ [ 24%]
+........................................................................ [ 27%]
+........................................................................ [ 29%]
+........................................................................ [ 31%]
+........................................................................ [ 33%]
+........................................................................ [ 35%]
+........................................................................ [ 37%]
+........................................................................ [ 39%]
+........................................................................ [ 41%]
+........................................................................ [ 43%]
+........................................................................ [ 45%]
+........................................................................ [ 47%]
+........................................................................ [ 49%]
+........................................................................ [ 51%]
+........................................................................ [ 54%]
+........................................................................ [ 56%]
+........................................................................ [ 58%]
+........................................................................ [ 60%]
+........................................................................ [ 62%]
+........................................................................ [ 64%]
+........................................................................ [ 66%]
+........................................................................ [ 68%]
+........................................................................ [ 70%]
+........................................................................ [ 72%]
+........................................................................ [ 74%]
+........................................................................ [ 76%]
+........................................................................ [ 79%]
+........................................................................ [ 81%]
+........................................................................ [ 83%]
+........................................................................ [ 85%]
+........................................................................ [ 87%]
+........................................................................ [ 89%]
+........................................................................ [ 91%]
+........................................................................ [ 93%]
+........................................................................ [ 95%]
+........................................................................ [ 97%]
+........................................................................ [ 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/auth.py 52 0 100%
+app/api/chat.py 270 1 99%
+app/api/chat_images.py 50 0 100%
+app/api/chats.py 110 0 100%
+app/api/config.py 13 0 100%
+app/api/doc_drafts.py 99 0 100%
+app/api/docs.py 196 1 99%
+app/api/git_sources.py 259 0 100%
+app/api/health.py 10 0 100%
+app/api/steering.py 42 0 100%
+app/api/suggestions.py 33 0 100%
+app/api/sync.py 183 0 100%
+app/api/tokens.py 40 0 100%
+app/api/ui_settings.py 55 0 100%
+app/config.py 265 0 100%
+app/core/__init__.py 0 0 100%
+app/core/auth.py 45 0 100%
+app/core/caching.py 124 0 100%
+app/core/debugging.py 29 2 93%
+app/core/docs_push.py 39 0 100%
+app/core/errors.py 5 0 100%
+app/core/logging.py 13 0 100%
+app/core/rate_limit.py 44 0 100%
+app/core/security_headers.py 20 0 100%
+app/core/theming.py 38 0 100%
+app/core/tokens.py 44 0 100%
+app/db.py 22 0 100%
+app/main.py 68 0 100%
+app/models.py 135 0 100%
+app/rag/__init__.py 0 0 100%
+app/rag/agent.py 431 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 744 4 99%
+app/rag/llm.py 246 1 99%
+app/rag/md_images.py 63 0 100%
+app/rag/overview.py 71 0 100%
+app/rag/pdf.py 124 0 100%
+app/rag/prompts.py 155 0 100%
+app/rag/retriever.py 248 3 99%
+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 58 0 100%
+app/schemas.py 443 0 100%
+--------------------------------------------------
+TOTAL 5609 17 99%
+coverage gate: app/ 99% (>90%) OK
+All checks passed!
+0 errors, 0 warnings, 0 informations
+WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414).
+Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
+
+validation OK
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.err b/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.err
new file mode 100644
index 0000000..e69de29
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.md b/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.md
new file mode 100644
index 0000000..e5e4443
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.md
@@ -0,0 +1,18 @@
+All green. Task complete.
+
+**Implemented (task 02 — box styling):**
+- `.sync-progress` panel in `frontend/assets/styles.css`: house bordered-panel language (`--surface` fill, 1px `--line` border, `--radius` radius, `0.75rem 1rem` padding, `min-height: 4rem` ≈ 2 lines). No `margin-top` — the `.sources-shell` flex gap (1.25rem) *is* the house spacing; a margin would double it (documented in the CSS comment)
+- `.sync-progress-text`: `display: block`, `var(--mono)`, `0.8rem` (the `.sync-result` size), house `1.55` line-height, `var(--ink-soft)` (pinned identity pair on `--surface`: 8.2:1 built-in dark, theme gate keeps all themes ≥4.5:1), `overflow-wrap: anywhere` — long paths WRAP, never clip
+- `.sync-btn.is-running .sync-label { display: none }` — icon-only footprint (16px icon centered in a ~47×44 pill; mobile keeps the full-width 44px bar via the pre-existing `width: 100%` rule); viewport-agnostic, defined once. Hover/`:disabled`/`:focus-visible`/`prefers-reduced-motion` untouched (they live on the button; the spinner kill at L2202 stands)
+- Mobile media query: verified no changes needed (box is a block in the 72rem container — full-width at 360–390px; no dead mobile label rules — idle label still renders, ellipsis rules kept)
+- **Defect fix (task 01 work):** `test_sync_label_mobile.py::test_pre_phase_css_reproduces_the_clip` went vacuous — its injected pre-phase rules (0,1,0) lost to the new (0,2,0) hide rule, leaving the parts `display:none`. The counterfactual injection set now also neutralizes the phase-149 hide rule (it didn't exist pre-phase), restoring the clip-geometry pin
+
+**Validation — 100% green:**
+- `uv run pytest --cov=app --cov-report=term` → 3463 passed, `app/` coverage 99% (>90%)
+- All 11 sync/upload E2E files pass in isolation: test_sync_button (3), test_sync_label_mobile (4), test_sync_cancel (3), test_sync_chunk_progress (2), test_sync_summary_visibility (3), test_sync_upload_progress (4), test_sync_changed_only (3), test_sync_model_down (4), test_force_push_resync (2), test_archive_upload_sources (5), test_upload_no_scan (3)
+- `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors, 0 warnings
+- Visual verification: 8 screenshots (desktop/mobile × dark/light × idle/running) — bordered mono panel with wrapped long path, icon-only spinner button, "Sync sources" pill restored at idle, AA contrast both themes
+
+**Docs:** no doc impact (feature-level README text stays accurate; no commands/env/API/convention changes)
+
+**Next pending task:** `03_e2e_progress_box.md` (the dedicated in-flight/settled Playwright suite)
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.validate b/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.validate
new file mode 100644
index 0000000..71a2985
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__02_progress_box_styles.a1.validate
@@ -0,0 +1,120 @@
+........................................................................ [ 2%]
+........................................................................ [ 4%]
+........................................................................ [ 6%]
+........................................................................ [ 8%]
+........................................................................ [ 10%]
+........................................................................ [ 12%]
+........................................................................ [ 14%]
+........................................................................ [ 16%]
+........................................................................ [ 18%]
+........................................................................ [ 20%]
+........................................................................ [ 22%]
+........................................................................ [ 24%]
+........................................................................ [ 27%]
+........................................................................ [ 29%]
+........................................................................ [ 31%]
+........................................................................ [ 33%]
+........................................................................ [ 35%]
+........................................................................ [ 37%]
+........................................................................ [ 39%]
+........................................................................ [ 41%]
+........................................................................ [ 43%]
+........................................................................ [ 45%]
+........................................................................ [ 47%]
+........................................................................ [ 49%]
+........................................................................ [ 51%]
+........................................................................ [ 54%]
+........................................................................ [ 56%]
+........................................................................ [ 58%]
+........................................................................ [ 60%]
+........................................................................ [ 62%]
+........................................................................ [ 64%]
+........................................................................ [ 66%]
+........................................................................ [ 68%]
+........................................................................ [ 70%]
+........................................................................ [ 72%]
+........................................................................ [ 74%]
+........................................................................ [ 76%]
+........................................................................ [ 79%]
+........................................................................ [ 81%]
+........................................................................ [ 83%]
+........................................................................ [ 85%]
+........................................................................ [ 87%]
+........................................................................ [ 89%]
+........................................................................ [ 91%]
+........................................................................ [ 93%]
+........................................................................ [ 95%]
+........................................................................ [ 97%]
+........................................................................ [ 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/auth.py 52 0 100%
+app/api/chat.py 270 1 99%
+app/api/chat_images.py 50 0 100%
+app/api/chats.py 110 0 100%
+app/api/config.py 13 0 100%
+app/api/doc_drafts.py 99 0 100%
+app/api/docs.py 196 1 99%
+app/api/git_sources.py 259 0 100%
+app/api/health.py 10 0 100%
+app/api/steering.py 42 0 100%
+app/api/suggestions.py 33 0 100%
+app/api/sync.py 183 0 100%
+app/api/tokens.py 40 0 100%
+app/api/ui_settings.py 55 0 100%
+app/config.py 265 0 100%
+app/core/__init__.py 0 0 100%
+app/core/auth.py 45 0 100%
+app/core/caching.py 124 0 100%
+app/core/debugging.py 29 2 93%
+app/core/docs_push.py 39 0 100%
+app/core/errors.py 5 0 100%
+app/core/logging.py 13 0 100%
+app/core/rate_limit.py 44 0 100%
+app/core/security_headers.py 20 0 100%
+app/core/theming.py 38 0 100%
+app/core/tokens.py 44 0 100%
+app/db.py 22 0 100%
+app/main.py 68 0 100%
+app/models.py 135 0 100%
+app/rag/__init__.py 0 0 100%
+app/rag/agent.py 431 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 744 4 99%
+app/rag/llm.py 246 1 99%
+app/rag/md_images.py 63 0 100%
+app/rag/overview.py 71 0 100%
+app/rag/pdf.py 124 0 100%
+app/rag/prompts.py 155 0 100%
+app/rag/retriever.py 248 3 99%
+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 58 0 100%
+app/schemas.py 443 0 100%
+--------------------------------------------------
+TOTAL 5609 17 99%
+coverage gate: app/ 99% (>90%) OK
+All checks passed!
+0 errors, 0 warnings, 0 informations
+WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414).
+Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
+
+validation OK
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.err b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.err
new file mode 100644
index 0000000..e69de29
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.md b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.md
new file mode 100644
index 0000000..fc70928
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.md
@@ -0,0 +1,16 @@
+All gates green. Final report:
+
+**Implemented**
+- `tests/e2e/test_sync_progress_box.py` — dedicated phase-149 E2E (5 tests, module app with `BOR_GIT_SOURCES=file://` fixture repo + own `BOR_SOURCES_DIR` + slow-LLM proxy, 1.5s): spinner-only button while running (`is-running`, `is-spinning`, `#sync-label` hidden, `aria-label` == box text, Cancel visible, box `aria-hidden`); box carries the EXACT full untruncated long-path label (wrap proof `scrollWidth <= clientWidth`, announcer `#sync-result` + `aria-label` equal, contrast ≥4.5:1) with the phase-129 `· chunk n/m` part pinned in the box over the slow embed window; mobile 390×844 box full-width + icon-only full-width button + wrapped full path; settle restores the byte-identical pill (`Synced HH:MM`, `aria-label` "Sync sources", `3 added`, box hidden); mid-run reload re-attaches with the box visible.
+
+**Test / lint / coverage**
+- `uv run pytest tests/e2e/test_sync_progress_box.py -v --no-cov` → **5 passed** in isolation (×2 runs, ~205s)
+- `uv run pytest --cov=app` → **3463 passed**, app coverage **99%**
+- `uv run ruff check . && uv run pyright` → **clean**
+- All 8 pre-existing sync E2Es green: button (3), cancel (3), chunk_progress (2), label_mobile (4), summary_visibility (3), upload_progress (4), model_down (4), changed_only (3)
+
+**Docs** — no doc impact (README's sync section was already updated by tasks 01/02; AGENTS.md unaffected).
+
+**Decisions** — mobile button full-width reference is the `.page-head` card content width (its containing block), not the `.container`; added a failed-terminal diagnostic print in the boundary wait (surfaced a test-cascade, not an app defect — both post-fix full runs fully green).
+
+**Next pending task** — none for phase 149 (task 03 was the last; harness moves the phase on completion).
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.validate b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.validate
new file mode 100644
index 0000000..71a2985
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a1.validate
@@ -0,0 +1,120 @@
+........................................................................ [ 2%]
+........................................................................ [ 4%]
+........................................................................ [ 6%]
+........................................................................ [ 8%]
+........................................................................ [ 10%]
+........................................................................ [ 12%]
+........................................................................ [ 14%]
+........................................................................ [ 16%]
+........................................................................ [ 18%]
+........................................................................ [ 20%]
+........................................................................ [ 22%]
+........................................................................ [ 24%]
+........................................................................ [ 27%]
+........................................................................ [ 29%]
+........................................................................ [ 31%]
+........................................................................ [ 33%]
+........................................................................ [ 35%]
+........................................................................ [ 37%]
+........................................................................ [ 39%]
+........................................................................ [ 41%]
+........................................................................ [ 43%]
+........................................................................ [ 45%]
+........................................................................ [ 47%]
+........................................................................ [ 49%]
+........................................................................ [ 51%]
+........................................................................ [ 54%]
+........................................................................ [ 56%]
+........................................................................ [ 58%]
+........................................................................ [ 60%]
+........................................................................ [ 62%]
+........................................................................ [ 64%]
+........................................................................ [ 66%]
+........................................................................ [ 68%]
+........................................................................ [ 70%]
+........................................................................ [ 72%]
+........................................................................ [ 74%]
+........................................................................ [ 76%]
+........................................................................ [ 79%]
+........................................................................ [ 81%]
+........................................................................ [ 83%]
+........................................................................ [ 85%]
+........................................................................ [ 87%]
+........................................................................ [ 89%]
+........................................................................ [ 91%]
+........................................................................ [ 93%]
+........................................................................ [ 95%]
+........................................................................ [ 97%]
+........................................................................ [ 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/auth.py 52 0 100%
+app/api/chat.py 270 1 99%
+app/api/chat_images.py 50 0 100%
+app/api/chats.py 110 0 100%
+app/api/config.py 13 0 100%
+app/api/doc_drafts.py 99 0 100%
+app/api/docs.py 196 1 99%
+app/api/git_sources.py 259 0 100%
+app/api/health.py 10 0 100%
+app/api/steering.py 42 0 100%
+app/api/suggestions.py 33 0 100%
+app/api/sync.py 183 0 100%
+app/api/tokens.py 40 0 100%
+app/api/ui_settings.py 55 0 100%
+app/config.py 265 0 100%
+app/core/__init__.py 0 0 100%
+app/core/auth.py 45 0 100%
+app/core/caching.py 124 0 100%
+app/core/debugging.py 29 2 93%
+app/core/docs_push.py 39 0 100%
+app/core/errors.py 5 0 100%
+app/core/logging.py 13 0 100%
+app/core/rate_limit.py 44 0 100%
+app/core/security_headers.py 20 0 100%
+app/core/theming.py 38 0 100%
+app/core/tokens.py 44 0 100%
+app/db.py 22 0 100%
+app/main.py 68 0 100%
+app/models.py 135 0 100%
+app/rag/__init__.py 0 0 100%
+app/rag/agent.py 431 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 744 4 99%
+app/rag/llm.py 246 1 99%
+app/rag/md_images.py 63 0 100%
+app/rag/overview.py 71 0 100%
+app/rag/pdf.py 124 0 100%
+app/rag/prompts.py 155 0 100%
+app/rag/retriever.py 248 3 99%
+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 58 0 100%
+app/schemas.py 443 0 100%
+--------------------------------------------------
+TOTAL 5609 17 99%
+coverage gate: app/ 99% (>90%) OK
+All checks passed!
+0 errors, 0 warnings, 0 informations
+WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414).
+Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
+
+validation OK
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.err b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.err
new file mode 100644
index 0000000..e69de29
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.md b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.md
new file mode 100644
index 0000000..c912335
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.md
@@ -0,0 +1,14 @@
+**What was fixed**
+- No code defects found: the prior rejection was a missing final report (the harness's own a1 validation passed — coverage gate OK, ruff, pyright). Re-verified everything and tightened the README settle sentence (was "idle 'Sync sources' pill returns"; now byte-accurate: "Synced HH:MM" pill after success with the counts line, retry-ready "Sync sources" after failure/cancel — matching the E2E-pinned `settleSyncButton`/`applySyncSuccess` behavior).
+
+**Test / lint / coverage (all re-run this pass)**
+- `uv run pytest --cov=app --cov-report=term-missing` → **3463 passed**, app coverage **99%** (>90% gate)
+- `uv run ruff check . && uv run pyright` → **clean** (0 errors)
+- `uv run pytest tests/e2e/test_sync_progress_box.py -v --no-cov` → **5 passed** in isolation (198s)
+- Pre-existing sync E2Es (button/cancel/chunk_progress/label_mobile/summary_visibility/upload_progress/model_down/changed_only): **26 passed** (run on this same tree; only README changed since)
+
+**Docs** — README.md settle contract corrected (doc-only); AGENTS.md re-checked, no sync-UI content, no changes.
+
+**Notable decisions** — README edit is documentation-only (not served by the app, no test impact); the phase-149 sync section otherwise verified accurate against the E2E pins (spinner-only button, `aria-hidden` box, A4 single live region, 409/cancel contracts).
+
+**Next pending task** — none; task 03 is the last task of phase 149 (harness completes the phase).
diff --git a/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.validate b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.validate
new file mode 100644
index 0000000..71a2985
--- /dev/null
+++ b/.agents/reports/149_sync_progress_box/149_sync_progress_box__03_e2e_progress_box.a2.validate
@@ -0,0 +1,120 @@
+........................................................................ [ 2%]
+........................................................................ [ 4%]
+........................................................................ [ 6%]
+........................................................................ [ 8%]
+........................................................................ [ 10%]
+........................................................................ [ 12%]
+........................................................................ [ 14%]
+........................................................................ [ 16%]
+........................................................................ [ 18%]
+........................................................................ [ 20%]
+........................................................................ [ 22%]
+........................................................................ [ 24%]
+........................................................................ [ 27%]
+........................................................................ [ 29%]
+........................................................................ [ 31%]
+........................................................................ [ 33%]
+........................................................................ [ 35%]
+........................................................................ [ 37%]
+........................................................................ [ 39%]
+........................................................................ [ 41%]
+........................................................................ [ 43%]
+........................................................................ [ 45%]
+........................................................................ [ 47%]
+........................................................................ [ 49%]
+........................................................................ [ 51%]
+........................................................................ [ 54%]
+........................................................................ [ 56%]
+........................................................................ [ 58%]
+........................................................................ [ 60%]
+........................................................................ [ 62%]
+........................................................................ [ 64%]
+........................................................................ [ 66%]
+........................................................................ [ 68%]
+........................................................................ [ 70%]
+........................................................................ [ 72%]
+........................................................................ [ 74%]
+........................................................................ [ 76%]
+........................................................................ [ 79%]
+........................................................................ [ 81%]
+........................................................................ [ 83%]
+........................................................................ [ 85%]
+........................................................................ [ 87%]
+........................................................................ [ 89%]
+........................................................................ [ 91%]
+........................................................................ [ 93%]
+........................................................................ [ 95%]
+........................................................................ [ 97%]
+........................................................................ [ 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/auth.py 52 0 100%
+app/api/chat.py 270 1 99%
+app/api/chat_images.py 50 0 100%
+app/api/chats.py 110 0 100%
+app/api/config.py 13 0 100%
+app/api/doc_drafts.py 99 0 100%
+app/api/docs.py 196 1 99%
+app/api/git_sources.py 259 0 100%
+app/api/health.py 10 0 100%
+app/api/steering.py 42 0 100%
+app/api/suggestions.py 33 0 100%
+app/api/sync.py 183 0 100%
+app/api/tokens.py 40 0 100%
+app/api/ui_settings.py 55 0 100%
+app/config.py 265 0 100%
+app/core/__init__.py 0 0 100%
+app/core/auth.py 45 0 100%
+app/core/caching.py 124 0 100%
+app/core/debugging.py 29 2 93%
+app/core/docs_push.py 39 0 100%
+app/core/errors.py 5 0 100%
+app/core/logging.py 13 0 100%
+app/core/rate_limit.py 44 0 100%
+app/core/security_headers.py 20 0 100%
+app/core/theming.py 38 0 100%
+app/core/tokens.py 44 0 100%
+app/db.py 22 0 100%
+app/main.py 68 0 100%
+app/models.py 135 0 100%
+app/rag/__init__.py 0 0 100%
+app/rag/agent.py 431 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 744 4 99%
+app/rag/llm.py 246 1 99%
+app/rag/md_images.py 63 0 100%
+app/rag/overview.py 71 0 100%
+app/rag/pdf.py 124 0 100%
+app/rag/prompts.py 155 0 100%
+app/rag/retriever.py 248 3 99%
+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 58 0 100%
+app/schemas.py 443 0 100%
+--------------------------------------------------
+TOTAL 5609 17 99%
+coverage gate: app/ 99% (>90%) OK
+All checks passed!
+0 errors, 0 warnings, 0 informations
+WARNING: there is a new pyright version available (v1.1.411 -> v1.1.414).
+Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
+
+validation OK
diff --git a/README.md b/README.md
index c264e97..25ed7cb 100644
--- a/README.md
+++ b/README.md
@@ -326,14 +326,21 @@ whole git-source refresh in one click:
rows, not the whole table); an unchanged re-sync instead gap-fills
any missing rows (`only_missing`).
-- States: the button shows **Syncing…** with a spinner while polling
- `GET /api/sync/status` every 2 s. During the import phase the label
- carries the live file, its `(n/m)` file position, and — while a file's
- embed batch is in flight — the pinned `· chunk n/m` embed position
- (batch granularity: the first chunk of the in-flight batch over the
- file's total content chunks); the full untruncated label also rides
- the button title and the aria-live result line. No client-side
- timeout — a clone + embed can legitimately take minutes.
+- States: while polling `GET /api/sync/status` every 2 s, the button
+ becomes the spinner (icon only — its label parts are hidden while a
+ run is in flight, and its accessible name is the full live label),
+ and the full live detail — "Syncing…