phase: 134_sync_cancel
Build and Push Containers / build-and-push-app (push) Successful in 2m26s
Build and Push Containers / build-and-push-db (push) Successful in 13s

**Phase 134 final verification pass — all green** (all 3 task files already in `complete/`; no implementation was missing)

- Verified: 5-state `SyncStatus` + `cancelled` terminal (error None, final counts kept), `POST /api/sync/cancel` (202/409/403), cooperative `_check_cancelled` boundaries, shutdown `CancelledError` contract preserved, `#sync-cancel-btn` show/hide + neutral "Sync cancelled" settle, 8-branch poll tree, re-attach — code, unit, integration, and E2E layers all present
- `uv run pytest --cov=app --cov-report=term-missing` → **3150 passed**, `app/` coverage **99%** (gate: >90%)
- `uv run pytest tests/e2e/test_sync_cancel.py -v --no-cov` (isolated) → **3 passed** (47.6 s)
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings

**Completion criteria:** ① cancel endpoint 202/409/403 ✅ (unit + E2E) ② `cancelled` terminal reported by status, error null, counts kept ✅ (integration `test_cancel_mid_run_lands_in_cancelled_then_resyncs_clean`) ③ unrequested-cancel pin ✅ (`test_unrequested_cancel_is_never_swallowed_and_never_converts`) ④ UI lifecycle + clean re-sync (sentinel row, full 40-file import) ✅ (E2E) ⑤ suite/coverage/E2E gates ✅ ⑥ uncancelled runs byte-identical ✅ (all 3150 pre-existing tests green untouched)

- Docs: README.md reviewed in full against code (pages, auth endpoints, every config default vs `app/config.py`, palette 9+8, fail-loud, cancel section) — consistent, no changes needed. AGENTS.md: fixed one pre-existing inaccuracy (rule 2 "move its file" → "move its directory" — phases are directories); everything else verified accurate
- No live infrastructure touched; no deviations

**Next pending phase:** `135_git_source_branch`
This commit is contained in:
2026-09-28 18:08:11 -04:00
parent 25de518dc9
commit fcac876d40
26 changed files with 2535 additions and 30 deletions
+9
View File
@@ -466,6 +466,15 @@
<svg class="sync-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>
<span class="sync-label" id="sync-label"><span class="sync-label-main">Sync sources</span><span class="sync-label-count" hidden></span><span class="sync-label-chunk" hidden></span></span>
</button>
<!-- Phase 134 (task 02): the Cancel control — visible +
enabled ONLY while a sync run is in flight (the upload
job is not cancellable in this phase). Ships hidden
(anonymous-safe + the idle state; sources.js reveals
it the same way it reveals #sync-btn) and requests
the cancel on click (POST /api/sync/cancel). The
visible "Cancel" label is the accessible name (WCAG
2.4 — never an icon-only control). -->
<button type="button" id="sync-cancel-btn" class="sync-cancel-btn" hidden>Cancel</button>
</div>
<p class="page-sub">
Every file indexed from your configured sources — git repositories,