"""Unit: the per-source ignore-paths editor on the Sources page (phase 89, task 05). ``TODO.md`` L3: "They should be able to type these files and folders into a box on the sources page." Phase 89 gives every STORED source row (git or local) a one-path-per-line ignore box on ``/git-sources.html``: a page-local alertdialog (the EXACT ``#remove-confirm-dialog`` pattern, phase 69) with a visible label, a mono textarea prefilled from the row, the §7.4 never-stale save lifecycle ("Saving…" while the ``PATCH /api/git-sources/{id}`` is out — the A5 replace round-trips through ``GET``), and full a11y (focus on Cancel, Escape / backdrop close as CANCEL, focus return, ``role="alert"`` error line that keeps the textarea content on 422). Rows with a list show the ``N ignored`` count tag; env-fallback rows (``id`` null) get NO box (A3 — nothing is stored to edit). The browser behavior itself is E2E-gated by the phase-89 story suite (``tests/e2e/test_source_ignore_paths.py``, task 06); like the other frontend-adjacent unit files (the ``test_remove_confirm_modal.py`` house pattern), this module pins the source-level contract a silent regression would break: * the static ``#ignore-editor-dialog`` markup — ``role= "alertdialog"`` + ``aria-modal`` + ``aria-labelledby``, hidden by default, inside the manager, the visible ``