Skip to content

fix(devcontainer): wire the composition root before the FlashRank prewarm - #618

Merged
cdeust merged 1 commit into
mainfrom
fix/617-devcontainer-reranker-prewarm
Sep 22, 2026
Merged

cdeust merged 1 commit into
mainfrom
fix/617-devcontainer-reranker-prewarm

Conversation

@cdeust

@cdeust cdeust commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #617

Since #568 (issue #560), core/reranker_model.py requires configure_reranker_filesystem() to run before any core function that touches the reranker cache directory. .devcontainer/Dockerfile's FlashRank prewarm called _ensure_reranker() directly and never wired it, so every build failed the same way: 5 retries, the same RuntimeError each time. The HF/sentence-transformers prewarm line above it is unaffected, it does not touch the reranker seam.

This job is path-filtered and skipped on a push that does not touch Dockerfile-relevant paths, which is why it never blocked a release (confirmed on the 4.23.1 release push, run 35700002270: the job shows skipped, ci-green still passed). The daily scheduled run hit it for real: run 35586189593, 2026-09-21, job 106290069933.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Test plan

  • Ran the exact one-liner locally, twice, in a fresh Python process each time: without the wire_composition_root() call it raises RuntimeError: reranker cache_dir provider not configured; with it added, _ensure_reranker() returns a loaded reranker.
  • Grepped every Dockerfile in the repo (.devcontainer/Dockerfile, Dockerfile, docker/Dockerfile, .clusterfuzzlite/Dockerfile) for another bare python -c reaching mcp_server.core; the only other one imports mcp_server.__main__, which wires its own composition root on import.
  • python3 scripts/check_doc_claims.py and python3 scripts/check_craftsmanship.py --base origin/main, both OK.
  • The Docker Build (devcontainer image) CI job on this PR is the actual reproduction: it touches .devcontainer/Dockerfile, so it will not be skipped this time.

Audit notes

One-line change inside an existing RUN instruction; no new dependency, no change to what gets prewarmed or cached, only when the seam is wired first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NLvPnrr8Ab6cKPK1Kt3K7f

…warm

Closes #617

Since #568 (issue #560), core/reranker_model.py requires
configure_reranker_filesystem() to run before any core function that
touches the reranker cache directory. The devcontainer image's FlashRank
prewarm called _ensure_reranker() directly and never wired it, so every
build failed the same way, 5 retries, RuntimeError each time.

Verified locally: the exact one-liner still raises the RuntimeError
without the wire_composition_root() call added here, and returns a
loaded reranker with it. This job is skipped on a push that does not
touch Dockerfile-relevant paths (confirmed on the 4.23.1 release push,
run 35700002270), which is why it never blocked a release; the daily
scheduled run hit it for real (run 35586189593, 2026-09-21).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NLvPnrr8Ab6cKPK1Kt3K7f
Signed-off-by: cdeust <[email protected]>
@cdeust

cdeust commented Sep 22, 2026

Copy link
Copy Markdown
Owner Author

ZETETIC-REVIEW: APPROVE

Verified independently (read-only, no edits/commits). Findings ranked by severity; none block.

Findings

  1. (Informational) Cache path under root vs cortex user, confirmed non-issue. The prewarm RUN runs as root before USER cortex (Dockerfile line ~99, prior to line 105). ENV XDG_CACHE_HOME=/opt/model-cache is set at line 61, before the prewarm block, so mcp_server/shared/platform.py:cache_dir() (line 27, os.environ.get("XDG_CACHE_HOME")) resolves to /opt/model-cache, and reranker_cache_dir() (mcp_server/infrastructure/reranker_cache.py:23) writes to /opt/model-cache/flashrank. That whole tree is covered by chown -R cortex:cortex /opt/model-cache /workspace on Dockerfile line 104, which runs after the prewarm in the same RUN chain. No root-owned cache directory left behind for the cortex runtime user.

  2. (Informational) Py version mismatch in my local repro (py3.12 venv via uv sync) vs the image's python:3.14-slim. Not a concern: the CI job itself built and ran the one-liner inside the actual image (see item 5), which is the authoritative reproduction: my local run only independently confirms the wiring/exception behavior in isolation.

No other findings. Every item below checks out.

Verified claims

  1. mcp_server/hooks/wiring.py read in full. wire_composition_root() only calls configure_* functions that store function references (partial application via global assignment); it performs no I/O itself. Traced every function it wires in: reranker_cache_dir/reranker_model_exists/reranker_model_sha256 (mcp_server/infrastructure/reranker_cache.py, stdlib pathlib/hashlib only), mcp_server/infrastructure/config.py (WIKI_ROOT, pure pathlib.Path construction, no I/O per its own docstring), wiki_axis_fs.py, wiki_coverage_fs.py, wiki_dashboard_fs.py, wiki_drift_fs.py, shared/platform.py (all stdlib os/pathlib only). Also checked the modules wire_composition_root's import transits (mcp_server/__init__.py, mcp_server/hooks/__init__.py are docstring-only, no side effects). No PostgreSQL client, no socket/requests import, no settings instantiation anywhere in this call graph. Confirmed idempotent by calling wire_composition_root() twice in one process before _ensure_reranker(): no exception, second call is a no-op re-assignment as documented at wiring.py:72-75.

  2. Reproduced independently, not trusting the PR's report. Set up a fresh venv via uv sync --no-default-groups --extra dev --extra sqlite in the worktree, then ran the exact Dockerfile one-liner with .venv/bin/python -c "...", in fresh processes:

    • Without wire_composition_root(): raises RuntimeError: reranker cache_dir provider not configured, call configure_reranker_filesystem() at the composition root first, raised from mcp_server/core/reranker.py:70 via mcp_server/core/reranker_model.py:64. Matches the CI failure signature exactly.
    • With the fix (as it now appears in the Dockerfile): exit 0, twice in separate fresh processes. type(_ensure_reranker()) is flashrank.Ranker.Ranker, not a sentinel or None.
  3. Grepped the whole repo, not just Dockerfiles, for other bare invocations of _ensure_reranker, configure_reranker_filesystem, and the other core seam-configuration functions wired by wire_composition_root (configure_core_environment_reader, configure_default_wiki_root, configure_schema_file_reader, configure_wiki_coverage_filesystem, configure_wiki_drift_filesystem, configure_dashboard_filesystem). Searched *.py, *.yml/*.yaml, Dockerfile*, *.sh, Makefile, .github/workflows/*.yml. Every hit outside wiring.py itself is either: (a) _ensure_reranker calls inside tests_py/core/test_reranker.py and test_retrieval_telemetry.py, which is test-owned setup; (b) benchmarks/lib/retriever.py, which imports benchmarks.lib._composition_root_wiring (line 35), a module whose own top level calls wire_composition_root() on import, so it is wired; (c) docstring/comment mentions. Also confirmed wire_composition_root itself is called from every real entry point: mcp_server/__main__.py, scripts/launcher.py, every mcp_server/hooks/*.py script's own __main__ block, and benchmarks/lib/_composition_root_wiring.py. Checked .github/workflows/*.yml specifically: the python -c one-liners there touch sentence_transformers, tree_sitter_language_pack, JSON parsing of MCP config, and mcp_server.shared.platform (line 423); none reach the reranker seam. The PR's claim about checking Dockerfile, docker/Dockerfile, .clusterfuzzlite/Dockerfile for another bare python -c reaching mcp_server.core is accurate: .clusterfuzzlite/Dockerfile has no python -c at all, docker/Dockerfile has none either, and Dockerfile:141 has CMD python -c "import mcp_server.__main__".

  4. Confirmed mcp_server/__main__.py calls wire_composition_root() at true module level (line 74, right after the import block, before configure_user_rules_provider(...)), not inside a function or conditional. Reading Dockerfile:141's CMD python -c "import mcp_server.__main__" therefore does wire the composition root on import, as claimed. Not taken on trust.

  5. gh pr checks 618 polled until resolution. Docker Build (devcontainer image) (run 35700808477, job 106658343727) went from pending to a real result rather than being skipped, since this PR touches .devcontainer/Dockerfile: job passed in 5m7s. Pulled the raw job log via the GitHub API (not just the checks summary) and read the actual prewarm step output: step #15 [9/9] RUN ... retry FlashRank python -c "..." completed DONE 10.9s, with INFO:flashrank.Ranker:Downloading ms-marco-MiniLM-L-12-v2... on the first attempt and no RuntimeError, no prewarm attempt N failed retry-loop line at all, meaning it succeeded on attempt 1, not after retries. This is a real reproduction of the fix in the actual devcontainer image, not just a green checkmark.

  6. git diff origin/main...HEAD --stat confirms exactly one file changed, .devcontainer/Dockerfile, one insertion and one deletion (a single line). The diff only prepends from mcp_server.hooks.wiring import wire_composition_root; wire_composition_root(); before the existing _ensure_reranker() call inside the same python -c string; nothing else in the line changed, so what gets prewarmed/cached and the HF prewarm line above it are untouched. Confirmed no change to runtime behavior beyond wiring order.

@cdeust
cdeust merged commit 95f3bec into main Sep 22, 2026
25 checks passed
@cdeust
cdeust deleted the fix/617-devcontainer-reranker-prewarm branch September 22, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

devcontainer image build: FlashRank prewarm fails, core reranker seam never wired

1 participant