phase: 193_sync_remaining_count
Build and Push Containers / build-and-push-app (push) Successful in 2m3s
Build and Push Containers / build-and-push-db (push) Successful in 16s

**Phase 193 — final verification pass: all gates green.**

- **Verified (all 3 tasks already complete in `complete/193_sync_remaining_count/`):** `fmtSyncLabel`'s count part is `total > 0 && total - done > 0 ? \`${total - done} remaining\` : ""` (plain int, hidden at `N==0`, `total===0` → no part); docstrings updated; chunk/image/summaries parts + `counts_line` terminal + `app/` byte-untouched (`git diff --stat`: no `app/` files).
- **Completion criteria:** `N remaining` shape + marker pins ✅ · upload shares the builder (E2E upload arm) ✅ · chunk/image/summaries pins green ✅ · terminal `counts_line` green unedited + A4 title/`#sync-progress` pin ✅ · suite green, coverage 99% ✅ · lint/types clean ✅ · commit + `todo/→complete/` left to the harness (no git index/history commands run).
- `uv run pytest -q --cov=app --cov-report=term-missing` → **exit 0**, junit: **4792 tests, 0 failures/errors/skipped**, `TOTAL 7181 16 → 99%` (>90%)
- `uv run pytest tests/e2e/test_sync_remaining_count.py -v --no-cov` → **3 passed** (isolated, 53 s)
- Isolated `--no-cov` sweep of the 14 sync-lineage suites (label_mobile, upload_progress, chunk_progress, image_progress, progress_box, summary_visibility, archive_upload_sources, status_freshness, upload_no_scan, peak_memory_visible, session_reset, fast_path_deferred_content, git_freeze, smoke) → **14/14 exit 0**
- `uv run ruff check .` → All checks passed · `uv run pyright` → **0 errors**
- **Docs:** README.md reviewed in full (all 2408 lines) + AGENTS.md. Fixed 2 inconsistencies: the sync running-label clause claimed the upload label shows the count — now states it shares the ONE builder/shape but reports no counts since phase 90 (renders bare); phase-190's "the other ~72 rows" → "the other 83 rows of the panel's 86-row catalogue" (mechanically: 86 CATALOG rows, 84 overridable). `N remaining` already in the sync paragraph; task-01's `(n/m)` examples gone. AGENTS.md verified consistent (no clause names the running count part → unchanged per the phase's "do not add if absent"). Mechanically re-verified: all 86 `BOR_*` settings documented + defaults match, `.env.example` 88 vars covered, 0 broken README anchors, all cited file paths exist, 17 palette colors, migrations head `0030`, pages/shell routes, ports 8123/8901, E2E port allocations (new suite's 8211/8914 unique).
- **Notable:** task 02's documented deviation stands — `files_done` is the importer's 1-based *current* file, so the phase doc's `[1-4]` range is unreachable; count-bearing frames are `1 … N−1` (pinned). Pre-existing, untouched: `E2E_APP_PORT_TOOLBUDGET`/`SAVEDOC` both 8129 and `SYNCUP`/`SYCNCEL` both 8133 — harmless under the one-suite-at-a-time rule.
- **Next pending phase:** none — `193_sync_remaining_count` is the last entry in `.agents/phases/todo/`.
This commit is contained in:
2026-10-19 17:30:03 -04:00
parent fb17d15fbe
commit ae080ac7f3
36 changed files with 2111 additions and 174 deletions
+17 -11
View File
@@ -727,12 +727,17 @@ only) runs the whole source refresh in one click:
- 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… <file> (n/m)" during the import
phase (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; and — while a PDF's images are being
described — the `· image n/m` vision position: the 1-based image
and the full live detail — "Syncing… <file> N remaining" during the
import phase (the live file, its `N remaining` file count — N =
total − done, shown while N ≥ 1 and hidden at the final file, since
the owner reads the distance to the end better than the position in
the whole; the upload's `Importing` label shares the ONE builder and
the same shape, though since phase 90 that run reports no counts, so
today it renders bare; 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; and — while a PDF's images are being described — the
`· image n/m` vision position: the 1-based image
about to be described over the file's total images, ONE continuous
counter across the PDF's three vision spans, so a long image pass
visibly climbs instead of sitting frozen on the last chunk
@@ -2001,11 +2006,12 @@ to the OPEN document through the ONE shared brand pass (`assets/brand.js`'s
header brand, the footer line and the chat composer placeholder update on the
click, no reload — including a rename of an app whose old name is already on
the page. The re-apply runs only when one of those three keys was involved (the
other ~72 rows cost no extra request), never stacks a second fetch while one is
in flight, and a failed one leaves the page exactly as it showed — the save's
own status or error line stays the feedback. The Theme tab runs the same pass
after its Save and its Reset; it no longer edits the strings, so that read is
what keeps an open tab honest about a name the panel changed meanwhile.
other 83 rows of the panel's 86-row catalogue cost no extra request), never
stacks a second fetch while one is in flight, and a failed one leaves the page
exactly as it showed — the save's own status or error line stays the feedback.
The Theme tab runs the same pass after its Save and its Reset; it no longer
edits the strings, so that read is what keeps an open tab honest about a name
the panel changed meanwhile.
The whole contract — the incident regression (a color save no longer shadows a
later rename) and the live repaint of title / brand / footer / placeholder — is
pinned in a real browser by `tests/e2e/test_app_name_settings_fix.py` (run in