Sprint Item
#6 of 8 — Medium severity — land first Wednesday (PR 1 of 2; docs-only)
Block Relations
|
|
| Blocked by |
— (independent of cursor-browser #1–#5) |
| Blocks |
#7 — concurrency suite asserts the documented lock order |
| Repo/day |
Independent of #1–#5 |
Calendar Day
Wednesday, July 22, 2026 (PR 1 of 2 — docs-only; land before #7)
Planned Effort
5 story points (Medium) — sprint item #6
Problem
utils/search_index.py declares four module-global locks with no documented acquisition order, threading model, or single-worker assumption:
_index_lock (line 57)
_index_build_lock (line 58)
_background_lock_fd (line 60)
_usability_cache_lock (line 62)
The deployment surface — background refresh thread, atomic pointer swap, one-writer-per-host — is undocumented. A contributor cannot reason about safe lock nesting, and there is no stated single-worker constraint, so a multi-worker WSGI deploy would silently violate the design.
Goal
One docs-only PR that records the four locks and their permitted acquisition order (or the non-nested-by-design contract), documents the threading model and single-worker constraint, and adds a multi-worker WSGI warning to a deployment note. This doc becomes the invariant the concurrency suite (item #7) enforces.
Docs-only discipline (Week 3 retro learning): keep this PR docs-only. Do not fold in the concurrency test suite — that ships separately as test/search-index-concurrency (item #7).
Scope
Part A — lock inventory + order
- Record all four locks and their permitted acquisition order, or state explicitly that they are non-nested by design and must stay so.
- Describe current usage precisely:
_index_build_lock wraps build_search_index (line 521)
_index_lock guards _background_started
_usability_cache_lock guards the usability cache
_background_lock_fd is the cross-process advisory lock (lines 641-663)
_publish_active_index does the swap + prune (lines 187-219)
Part B — threading model
- Document: request threads read; one daemon thread writes; the active index is published by an atomic
search_index.active swap (readers see old or new, never partial).
- State the single-worker constraint, with a multi-worker WSGI warning in a deployment note.
Part C — where it lives
- Update
docs/architecture.md (around line 148) and/or README.md (lines 56-72) as the home for the lock-order + threading section; deployment note where the multi-worker warning belongs.
Out of scope
Acceptance Criteria
Verification
cd C:\Users\Jasen\CppAliance\claude-code-chat-browser
.\.venv\Scripts\Activate.ps1
# docs-only: link/lint checks
- Review: the documented order matches actual usage at
utils/search_index.py:57-63,187-219,521,641-693.
Sprint Item
#6 of 8 — Medium severity — land first Wednesday (PR 1 of 2; docs-only)
Block Relations
Calendar Day
Wednesday, July 22, 2026 (PR 1 of 2 — docs-only; land before #7)
Planned Effort
5 story points (Medium) — sprint item #6
Problem
utils/search_index.pydeclares four module-global locks with no documented acquisition order, threading model, or single-worker assumption:_index_lock(line 57)_index_build_lock(line 58)_background_lock_fd(line 60)_usability_cache_lock(line 62)The deployment surface — background refresh thread, atomic pointer swap, one-writer-per-host — is undocumented. A contributor cannot reason about safe lock nesting, and there is no stated single-worker constraint, so a multi-worker WSGI deploy would silently violate the design.
Goal
One docs-only PR that records the four locks and their permitted acquisition order (or the non-nested-by-design contract), documents the threading model and single-worker constraint, and adds a multi-worker WSGI warning to a deployment note. This doc becomes the invariant the concurrency suite (item #7) enforces.
Scope
Part A — lock inventory + order
_index_build_lockwrapsbuild_search_index(line 521)_index_lockguards_background_started_usability_cache_lockguards the usability cache_background_lock_fdis the cross-process advisory lock (lines 641-663)_publish_active_indexdoes the swap + prune (lines 187-219)Part B — threading model
search_index.activeswap (readers see old or new, never partial).Part C — where it lives
docs/architecture.md(around line 148) and/orREADME.md(lines 56-72) as the home for the lock-order + threading section; deployment note where the multi-worker warning belongs.Out of scope
utils/search_index.py.Acceptance Criteria
search_index.activeswap.Verification
utils/search_index.py:57-63,187-219,521,641-693.