Two release-blocking fixes for v3.3.6:
1. CI ruff pin drift
.github/workflows/ci.yml installed ruff==0.15.9 while pyproject.toml
[dev] extras and .pre-commit-config.yaml both pin 0.15.14. Ruff's
formatter output can change between minor versions, so a contributor
running `pip install -e ".[dev]"` and formatting locally with 0.15.14
would produce output the 0.15.9 lint job rejects. Same failure mode
that surfaced on PR #1579 (2026-05-22). Aligning CI to 0.15.14 keeps
the three pin sites in lock-step.
2. COCA filter imports inside per-drawer hot paths
PR #1605 (COCA content-word filter, shipping in 3.3.6) introduced
`from .entity_detector import _get_coca_filter` and
`from .palace import _candidate_entity_words` inside
_extract_entities_for_metadata (called per drawer) and
build_closet_lines (called per closet). Python caches module imports
so the runtime cost after the first call is small, but the import
machinery still runs Python bytecode every invocation — gemini
flagged this on the original PR. Hoisting to module-level removes
the per-call import overhead.
The hoist is identical to PR #1612, which targets develop. Folding
it into the release so 3.3.6 doesn't ship the perf regression that
3.3.7 would immediately have to fix.
Verification: ruff check + format clean on 0.15.14, full pytest
(2258 passed / 12 skipped) on Linux Py 3.9 / 3.11 / 3.13 via
`pip install -e ".[dev]"` (CI-matching).