Repository navigation
fix(core): remove os/pathlib from ablation.py and 8 retrieval env-flag modules (#560, 2/3) - #568
Conversation
…all (#560) Root cause of the PR #568 CI failure (5 python versions red): the reranker preload step in .github/actions/test-suite calls mcp_server.core.reranker.ensure_reranker_loaded() as a bare `python -c` one-liner, which never imports mcp_server/__main__.py or tests_py/conftest.py, so core/reranker_model.py's filesystem seam (configure_reranker_filesystem) was never wired -- reranker_cache_dir() raised RuntimeError on every attempt. Audited every other bare entry point that could reach a #560 injection seam (scripts/, .github/, benchmarks/) without going through a composition root: the reranker was the only one with real exposure -- every core/environment.py-backed seam (ablation, telemetry, thermodynamics, etc.) degrades to a safe default instead of raising when unconfigured, and no other bare script/CI step touches mcp_server.core.reranker. Fix: mcp_server/doctor.py (already a composition root -- it imports both handlers and infrastructure freely, unlike core/ or infrastructure/ themselves) gains ensure_reranker_ready(), which wires the seam (idempotent) and then delegates to core.reranker.ensure_reranker_loaded(). CI's preload step now calls that instead of reaching into core directly. New regression test proves it self-wires even when the seam was reset to simulate a bare-script call. Verified: `python -c "from mcp_server.doctor import ensure_reranker_ready as e; s = e(); assert s.state == 'loaded', s"` (the exact CI command) passes locally; `python scripts/verify_mcp_hosts.py -- hypermnesia-mcp` (the second red CI check, "server exited -9") passes cleanly on all 6 client/profile combinations on this branch -- that failure did not reproduce locally and is likely a transient/resource-contention effect downstream of the first failure, not a code defect; re-run in CI to confirm now that the real root cause is fixed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
f9a3eb4 to
024fe55
Compare
|
ZETETIC-REVIEW: REQUEST_CHANGES Reviewed at 024fe55.
|
Addresses the reviewer's explicit "apply the same no-silent-default rule to #569, for example a wiki-root seam that falls back to a default path" note on PR #568's review. get_registry() used to collapse "configure_default_wiki_root was never called" and "the configured provider legitimately returned None" into the same wiki_root=None -> defaults-only behavior. The first case is a missing composition root, not a valid answer, and silently degrading to built-in defaults would hide any wiki-relative custom axis taxonomy a user configured via _schema/ files (CLAUDE.md: no silent fallbacks). Now: an explicitly-configured provider that returns None still yields defaults-only (unchanged, legitimate); a provider that was never configured at all raises RuntimeError. Wired tests_py/_composition_root_wiring.py's configure_default_wiki_root(lambda: None) explicitly, matching the test session's pre-existing implicit behavior (conftest.py isolates tests from any real wiki data) but now stated rather than silently defaulted. All 78 tests across test_wiki_axis_registry.py, test_wiki_classifier.py, test_ble001_sweep_core.py, and test_craftsmanship_imports.py pass unchanged. Also fixed a malformed `source: ADR-0297, issue #560` citation in wiki_coverage_fs.py's docstring (decision-integrity gate parses the first token after "source:" as a single decision ID; a trailing comma made it unparseable) -- same class of typo already fixed elsewhere in this PR, missed on this file. Verified: scripts/check_craftsmanship.py --base origin/main returns OK; pyright mcp_server/ reports 0 errors; full pytest reports 8447 passed, 165 skipped, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…al entry point Addresses ZETETIC-REVIEW: REQUEST_CHANGES on PR #568 (024fe55). Critical fix: core/environment.read_environment_variable used to return None when no reader was configured -- a silent fallback CLAUDE.md forbids. benchmarks/lib/ablation_runner.py sets CORTEX_ABLATE_<NAME>=1 in-process and calls a benchmark's run_benchmark() directly, never importing mcp_server/__main__.py, scripts/launcher.py, or tests_py/conftest.py. With the silent None default, every ablation measurement on this branch silently scored the un-ablated system, invalidating the published E1/E2 evidence the ablation results cite. Same class of exposure for every other benchmarks/**/run_*.py and scripts/ entry that reads a CORTEX_*_BETA / CORTEX_DECAY_* / CORTEX_RERANKER_OFFLINE flag. Fix: read_environment_variable now raises RuntimeError when no reader was ever configured (an explicitly-wired reader returning None for one specific variable is still a legitimate "unset" answer -- only the never-configured case is a bug). Then wired every real composition root, enumerated mechanically rather than guessed: - scripts/launcher.py: the one process bootstrap shared by the plugin-installed server AND every hook (ADR-0742, `.claude-plugin/ plugin.json`'s hooks all route through `launcher.py mcp_server.hooks. <name>`) -- wiring it here once covers all of them without touching mcp_server/hooks/__init__.py (which would break capture_dispatch/ capture_worker's "must never import mcp_server.core" lazy-load invariant, tests_py/hooks/test_capture_dispatch.py). Verified this reasoning against the actual test: it does a bare `-c` import that never touches launcher.py at all, so wiring launcher.py cannot affect it either way -- confirmed capture_dispatch's 8 tests still pass. - Every one of the 14 hook scripts with `if __name__ == "__main__":` ALSO gets the wiring directly in that block (redundant with launcher.py, not with each other) -- this covers the one entry point launcher.py cannot reach: scripts/measure_pipeline_hook.py spawns `python -m mcp_server.hooks.pipeline_impact_bump` directly (bypassing launcher.py) while setting CORTEX_RERANKER_OFFLINE=1 to measure hook latency. Verified the fix on that exact invocation shape (runpy. run_module with run_name="__main__", matching what `-m` does). - benchmarks/lib/_composition_root_wiring.py: one new bootstrap (environment + the existing reranker seam) that every benchmarks/**/run_*.py, ablation_runner.py, and any benchmarks/lib module reaching core now imports. Six run_*.py already got this transitively via bench_db.py or retriever.py (both updated to the unified bootstrap); the other eleven needed an explicit import, added after each file's own sys.path setup so import order does not break. benchmarks/lib/run_e1_v3_lme.py and run_e1_v3_locomo.py were audited and excluded: they only orchestrate subprocesses of the already-wired run_benchmark.py scripts, never import core in-process. - mcp_server/doctor.py's ensure_reranker_ready() already self-wired its own seam (from the prior review round); unaffected by this change. New test tests_py/benchmarks/test_ablation_runner_wiring.py drives the literal ablation_runner.py entry path in a bare subprocess (no pytest conftest wiring) and proves CORTEX_ABLATE_ADAPTIVE_DECAY=1 actually disables the mechanism, plus proves an unwired bare script raises instead of silently reporting every mechanism enabled. Also: tests_py/test_doctor.py::TestEnsureRerankerReady:: test_self_wires_and_loads_even_when_the_seam_was_reset asserted `status.state == "loaded"`, which needs the FlashRank model on disk and failed in the SQLite CI job (does not preload it). Now asserts the seam is configured and reranker_cache_dir() does not raise, not that a model downloaded -- extracted the reset/restore logic into two helpers to stay under the 40-line method cap. Verified: scripts/check_craftsmanship.py --base origin/main returns OK; ruff check/format are clean; pyright mcp_server/ reports 0 errors; full pytest reports 8433+ passed, 0 failed (re-run after these changes); `CORTEX_ABLATE_ADAPTIVE_DECAY=1 python -c "..."` through scripts/launcher.py and through a bare runpy.run_module both confirmed disabling the mechanism; `python -c "from mcp_server.core.ablation import ...; is_mechanism_disabled(...)"` with no composition root confirmed raising RuntimeError. benchmarks/reproduce.sh --no-regression: Docker is available and the script is running against real data (LongMemEval-S downloaded and checksum-verified, locomo10.json present); the longmemeval-s benchmark stage is still executing after 35+ minutes of CPU time at the time of this commit. A full --no-regression run covers at least three benchmark suites (longmemeval-s, locomo, beam-100K) plus decision-ids and does not support --quick/--limit, so it cannot complete within one review turn. Reporting this honestly rather than claiming a result I do not have; the run continues and its output will be reported once available. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
Addressed all four points (commits 822c2f8, 523ea2d): 1. Silent fallback (critical).
New test This surfaced a real regression in 3 bare-subprocess telemetry tests that never wired anything (previously silently worked via the Also applied the same rule to #564 (re-audited: 2. Environment-dependent test. 3. Benchmark reproduction. Docker is available. Ran 4. PR #564 rebase. Done, rebased onto Final shas: #564 |
…t/axis_registry/coverage_dashboard (#560) Checkpoint commit, not yet pushed: 5 of the wiki-cluster's 6 modules done (wiki_coverage.py remains). Same injection-seam idiom as the ablation/ env-flag PR (#568), but this checkpoint has NOT yet been audited for the "unconfigured raises" ordering-contract problem the orchestrator flagged on that PR — every provider here needs the same audit before this is pushed for review. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
… modules Third and final PR of the multi-PR #560 fix: wiki_coverage.py (1330 lines, the largest of the 6 wiki-filesystem-cluster modules) had 5 functions doing real filesystem I/O (os.stat, os.listdir, os.walk, open+read). New mcp_server/infrastructure/wiki_coverage_fs.py holds all of it; core now goes through one configure_wiki_coverage_filesystem( stat_page=, markdown_file_sizes=, domain_kind_membership=, walk_source_files=, walk_markdown_contents=) injection point, wired by mcp_server/__main__.py and tests_py/_composition_root_wiring.py (the same idiom every other module in this multi-PR fix uses). - _has_substantive_anchor: os.stat -> injected stat_page(wiki_root, rel_path) -> (size, mtime) | None. - _count_substantive_pages: isdir+listdir+getsize -> injected markdown_file_sizes(dom_path) -> {filename: size}. - list_domains: isdir+listdir membership counting across known-kind directories -> injected domain_kind_membership(wiki_root, known_kinds) -> {candidate_domain: [kind, ...]}; the plausibility filter and >=2-kinds threshold stay in core as pure logic over the returned dict. - list_source_files: os.walk+splitext+relpath -> injected walk_source_files(root, skip_directories, source_extensions), core's own frozensets passed in as plain data (no I/O in the constants themselves). - _index_wiki_file_references: os.walk+open+read every .md file -> injected walk_markdown_contents(wiki_root) returning the raw text of every page; the regex token-extraction stays in core (pure). - Two bare os.path.basename() calls (pure string ops, not part of the walk) replaced with token.rsplit("/", 1)[-1]. - _SKIP_DIRECTORIES stopped duplicating the frozenset already extracted to mcp_server/shared/wiki_skip_directories.py for infrastructure/wiki_drift_fs.py's identical need (DRY boy-scout fix; that shared module exists specifically because infrastructure/ may not import core/, so the pure data had to move to shared/ for both infra modules to reuse). Also fixes a pyright regression introduced by wiki_axis_registry.py's fix in this same branch: configure_default_wiki_root's provider type changed from Path | str | None to str | None (core cannot reference Path even in a type hint without importing pathlib), so __main__.py's own configure_default_wiki_root(lambda: WIKI_ROOT) needed to become lambda: str(WIKI_ROOT) (WIKI_ROOT is a Path from infrastructure/config.py) -- caught by pyright, not by any test. Seam-fragility audit (per the #568/PR2 CI failure where a bare CI preload script bypassed every composition root and hit an unconfigured seam): grepped scripts/, .github/, benchmarks/, and mcp_server/hooks/ for every wiki_drift/wiki_axis_registry/wiki_coverage_dashboard/ wiki_coverage function and configure_* name introduced in this PR and the prior wiki-cluster commit -- zero hits outside mcp_server/__main__.py, tests_py/_composition_root_wiring.py, and handlers/. Unlike the reranker seam, these four wiki seams have no bare-script exposure today, so their "raise RuntimeError if unconfigured" design (correct here: a wiki audit silently returning "no drift found" when actually misconfigured is a worse failure mode than a loud crash, unlike an env-var read where "unconfigured = false" is a safe default) is not a live landmine. Also re-audited PR #564's abstention_gate.py (classifier_factory already degrades gracefully to no-filtering when unconfigured, confirmed safe) and codebase_graph.py (no I/O seam at all, pure string ops only). Fixes #560 (all 17 of the audited core/ modules that imported os or pathlib now have zero such imports; part 1/3 was PR #564, part 2/3 was PR #568). Verified: scripts/check_craftsmanship.py --base origin/main returns OK; grep for os/pathlib in this branch's 6 wiki modules returns empty; ruff check/format are clean; pyright mcp_server/ reports 0 errors; `python scripts/verify_mcp_hosts.py -- hypermnesia-mcp` passes on all 6 client/profile combinations; full pytest in progress at commit time (see hand-back notes for the confirmed count). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Addresses the reviewer's explicit "apply the same no-silent-default rule to #569, for example a wiki-root seam that falls back to a default path" note on PR #568's review. get_registry() used to collapse "configure_default_wiki_root was never called" and "the configured provider legitimately returned None" into the same wiki_root=None -> defaults-only behavior. The first case is a missing composition root, not a valid answer, and silently degrading to built-in defaults would hide any wiki-relative custom axis taxonomy a user configured via _schema/ files (CLAUDE.md: no silent fallbacks). Now: an explicitly-configured provider that returns None still yields defaults-only (unchanged, legitimate); a provider that was never configured at all raises RuntimeError. Wired tests_py/_composition_root_wiring.py's configure_default_wiki_root(lambda: None) explicitly, matching the test session's pre-existing implicit behavior (conftest.py isolates tests from any real wiki data) but now stated rather than silently defaulted. All 78 tests across test_wiki_axis_registry.py, test_wiki_classifier.py, test_ble001_sweep_core.py, and test_craftsmanship_imports.py pass unchanged. Also fixed a malformed `source: ADR-0297, issue #560` citation in wiki_coverage_fs.py's docstring (decision-integrity gate parses the first token after "source:" as a single decision ID; a trailing comma made it unparseable) -- same class of typo already fixed elsewhere in this PR, missed on this file. Verified: scripts/check_craftsmanship.py --base origin/main returns OK; pyright mcp_server/ reports 0 errors; full pytest reports 8447 passed, 165 skipped, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…569) * wip(core): remove os/pathlib from wiki_groomer/file_doc_skeleton/drift/axis_registry/coverage_dashboard (#560) Checkpoint commit, not yet pushed: 5 of the wiki-cluster's 6 modules done (wiki_coverage.py remains). Same injection-seam idiom as the ablation/ env-flag PR (#568), but this checkpoint has NOT yet been audited for the "unconfigured raises" ordering-contract problem the orchestrator flagged on that PR — every provider here needs the same audit before this is pushed for review. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> * fix(core): remove os/pathlib from wiki_coverage.py, last of #560's 17 modules Third and final PR of the multi-PR #560 fix: wiki_coverage.py (1330 lines, the largest of the 6 wiki-filesystem-cluster modules) had 5 functions doing real filesystem I/O (os.stat, os.listdir, os.walk, open+read). New mcp_server/infrastructure/wiki_coverage_fs.py holds all of it; core now goes through one configure_wiki_coverage_filesystem( stat_page=, markdown_file_sizes=, domain_kind_membership=, walk_source_files=, walk_markdown_contents=) injection point, wired by mcp_server/__main__.py and tests_py/_composition_root_wiring.py (the same idiom every other module in this multi-PR fix uses). - _has_substantive_anchor: os.stat -> injected stat_page(wiki_root, rel_path) -> (size, mtime) | None. - _count_substantive_pages: isdir+listdir+getsize -> injected markdown_file_sizes(dom_path) -> {filename: size}. - list_domains: isdir+listdir membership counting across known-kind directories -> injected domain_kind_membership(wiki_root, known_kinds) -> {candidate_domain: [kind, ...]}; the plausibility filter and >=2-kinds threshold stay in core as pure logic over the returned dict. - list_source_files: os.walk+splitext+relpath -> injected walk_source_files(root, skip_directories, source_extensions), core's own frozensets passed in as plain data (no I/O in the constants themselves). - _index_wiki_file_references: os.walk+open+read every .md file -> injected walk_markdown_contents(wiki_root) returning the raw text of every page; the regex token-extraction stays in core (pure). - Two bare os.path.basename() calls (pure string ops, not part of the walk) replaced with token.rsplit("/", 1)[-1]. - _SKIP_DIRECTORIES stopped duplicating the frozenset already extracted to mcp_server/shared/wiki_skip_directories.py for infrastructure/wiki_drift_fs.py's identical need (DRY boy-scout fix; that shared module exists specifically because infrastructure/ may not import core/, so the pure data had to move to shared/ for both infra modules to reuse). Also fixes a pyright regression introduced by wiki_axis_registry.py's fix in this same branch: configure_default_wiki_root's provider type changed from Path | str | None to str | None (core cannot reference Path even in a type hint without importing pathlib), so __main__.py's own configure_default_wiki_root(lambda: WIKI_ROOT) needed to become lambda: str(WIKI_ROOT) (WIKI_ROOT is a Path from infrastructure/config.py) -- caught by pyright, not by any test. Seam-fragility audit (per the #568/PR2 CI failure where a bare CI preload script bypassed every composition root and hit an unconfigured seam): grepped scripts/, .github/, benchmarks/, and mcp_server/hooks/ for every wiki_drift/wiki_axis_registry/wiki_coverage_dashboard/ wiki_coverage function and configure_* name introduced in this PR and the prior wiki-cluster commit -- zero hits outside mcp_server/__main__.py, tests_py/_composition_root_wiring.py, and handlers/. Unlike the reranker seam, these four wiki seams have no bare-script exposure today, so their "raise RuntimeError if unconfigured" design (correct here: a wiki audit silently returning "no drift found" when actually misconfigured is a worse failure mode than a loud crash, unlike an env-var read where "unconfigured = false" is a safe default) is not a live landmine. Also re-audited PR #564's abstention_gate.py (classifier_factory already degrades gracefully to no-filtering when unconfigured, confirmed safe) and codebase_graph.py (no I/O seam at all, pure string ops only). Fixes #560 (all 17 of the audited core/ modules that imported os or pathlib now have zero such imports; part 1/3 was PR #564, part 2/3 was PR #568). Verified: scripts/check_craftsmanship.py --base origin/main returns OK; grep for os/pathlib in this branch's 6 wiki modules returns empty; ruff check/format are clean; pyright mcp_server/ reports 0 errors; `python scripts/verify_mcp_hosts.py -- hypermnesia-mcp` passes on all 6 client/profile combinations; full pytest in progress at commit time (see hand-back notes for the confirmed count). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> * fix(core): wiki_axis_registry get_registry raises on an unwired seam Addresses the reviewer's explicit "apply the same no-silent-default rule to #569, for example a wiki-root seam that falls back to a default path" note on PR #568's review. get_registry() used to collapse "configure_default_wiki_root was never called" and "the configured provider legitimately returned None" into the same wiki_root=None -> defaults-only behavior. The first case is a missing composition root, not a valid answer, and silently degrading to built-in defaults would hide any wiki-relative custom axis taxonomy a user configured via _schema/ files (CLAUDE.md: no silent fallbacks). Now: an explicitly-configured provider that returns None still yields defaults-only (unchanged, legitimate); a provider that was never configured at all raises RuntimeError. Wired tests_py/_composition_root_wiring.py's configure_default_wiki_root(lambda: None) explicitly, matching the test session's pre-existing implicit behavior (conftest.py isolates tests from any real wiki data) but now stated rather than silently defaulted. All 78 tests across test_wiki_axis_registry.py, test_wiki_classifier.py, test_ble001_sweep_core.py, and test_craftsmanship_imports.py pass unchanged. Also fixed a malformed `source: ADR-0297, issue #560` citation in wiki_coverage_fs.py's docstring (decision-integrity gate parses the first token after "source:" as a single decision ID; a trailing comma made it unparseable) -- same class of typo already fixed elsewhere in this PR, missed on this file. Verified: scripts/check_craftsmanship.py --base origin/main returns OK; pyright mcp_server/ reports 0 errors; full pytest reports 8447 passed, 165 skipped, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> * fix(core): one composition root wires every #560 seam at every entry point Review of #569 found the wiki filesystem seams wired only in __main__ and the test conftest while they raise when unwired: the SessionStart-spawned hooks/consolidate_background.py runs consolidate with wiki=True in its own process, so every autonomous consolidation lost its dashboards (the sub-task error was recorded nested in stats and the cycle still reported status=ok). scripts/regenerate_file_docs.py had the same gap. - mcp_server/composition_root.py: wire_composition_root(), idempotent, wires the wiki root, the schema reader and the coverage, drift and dashboard filesystems in one place. - Called by __main__, scripts/launcher.py, every hooks/*.py __main__ block, every script and benchmark runner that reaches core. - tests_py/scripts/test_composition_root_wiring_coverage.py enumerates the entry points mechanically (plugin.json hook commands, hooks with a __main__ block, scripts and benchmarks importing core/handlers) and requires an actual wire_composition_root() call in each. - tests_py/hooks/test_consolidate_background_wiki_composition_root.py runs the hook as a real subprocess on a throwaway SQLite store without the test conftest. Measured: unwired, the hook logs "dashboards=error: RuntimeError: ... not configured"; wired, it logs "dashboards=written=0". The hook's wiki summary line now reports the dashboard outcome instead of defaulting to "ok". Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> * fix(core): wiring lives in hooks/, the one layer every entry point may import CI's craftsmanship gate refused hooks/* importing the top-level mcp_server.composition_root: the layer table lets hooks/ import core, infrastructure and shared only. hooks/ is also the only layer that may itself import both core and infrastructure and be imported by every entry point (the top-level __main__, scripts and benchmarks are not layer-checked), so the single wiring function moves to mcp_server/hooks/wiring.py. - post_tool_capture wires in _dispatch_with_store_cleanup, after the capture-mode gate, instead of inside process_event: excluded events still import nothing from core or infrastructure (W3-1b), and process_event stays within the 40-line cap. - Single-line imports keep post_commit_reindex.py under 300 lines. - The coverage test matches a real top-level main block, not the phrase quoted in a docstring. - Measured cost of the wiring import in a hook process: 24-35 ms cumulative (python -X importtime, 3 runs, this machine). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
…g modules (#560, 3/3) Last of the three #560 PRs (after #564 and #569): ablation.py, conflict_monitor.py, pg_recall_weights.py, recall_pipeline.py, reconsolidation.py, reranker_model.py, retrieval_dispatch.py, telemetry.py and thermodynamics.py no longer import os or pathlib. - core/environment.py: read_environment_variable/read_environment_float read through an injected reader, evaluated on every call, so runtime toggles (CORTEX_ABLATE_*, CORTEX_DECAY_DISABLED, CORTEX_*_BETA) still take effect after import. An unconfigured reader raises: returning "unset" silently would make every ablation run measure the un-ablated system (benchmarks set CORTEX_ABLATE_* without importing __main__). - core/reranker_model.py: the FlashRank cache lookup, existence check and sha256 move to infrastructure/reranker_cache.py behind a seam that raises when unwired. - Both seams join the wiki seams in mcp_server.hooks.wiring .wire_composition_root(), the single function every entry point calls. It now re-applies its bindings on every call instead of short-circuiting after the first, so a seam reset by a test is restored. The per-hook copies, benchmarks/lib/_environment_wiring.py, _reranker_wiring.py and the import-time wiring in hooks/_telemetry.py are gone; benchmarks/lib/_composition_root_wiring.py calls the same function. - doctor.ensure_reranker_ready() wires through that function; CI's reranker preload step calls it instead of reaching into core directly. - tests_py/benchmarks/test_ablation_runner_wiring.py drives the ablation-runner path with a CORTEX_ABLATE_* flag and proves the mechanism is disabled. Fixes #560 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
523ea2d to
5fee794
Compare
…#560) benchmarks/lib/ablation_runner.py imports db_snapshot, which imports psycopg; the SQLite-only CI job has no postgresql extra and failed at import. The PostgreSQL test jobs keep running it. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
ZETETIC-REVIEW: APPROVE Re-reviewed at b847b7c, base 872855f. Every point of the REQUEST_CHANGES verdict is addressed.
Benchmark command:
BEAM-100K and decision_ids also ran on the head. On the final state, the full suite passes (8630 tests), pyright reports 0 diagnostics, the craftsmanship gate passes with |
…warm (#618) 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). Claude-Session: https://claude.ai/code/session_01NLvPnrr8Ab6cKPK1Kt3K7f Signed-off-by: cdeust <[email protected]> Co-authored-by: Claude Sonnet 5 <[email protected]>
Summary
Second PR of the multi-PR #560 fix: 9 of the 17
mcp_server/core/modules that importosorpathlib(core is zero-I/O). Together with #564 (2 modules) this leaves only the wiki filesystem cluster (6 modules) for a third PR.New
mcp_server/core/environment.pyis the shared composition-root injection seam (configure_core_environment_reader/read_environment_variable/read_environment_float), the same idiom aswiki_axis_registry.configure_default_wiki_root(ADR-0292). Wired once, at process/session startup, bymcp_server/__main__.py,tests_py/conftest.py, andmcp_server/hooks/_telemetry.py.ablation.py:is_mechanism_disabled(mechanism)keeps its exact signature across roughly 111 call sites; reads the injected reader fresh on every call, matching ADR-0095's "DO NOT memoize" contract.conflict_monitor.py: its own_env_floathad zero callers anywhere in the repo (verified by grep) — deleted as dead code instead of migrated.pg_recall_weights.py:compute_pg_weights()readsCORTEX_DECAY_DISABLED/CORTEX_HEAT_CONSTANTlive on every call, matchingbenchmarks/lib/_e2_conditions.py's runtime env toggling.recall_pipeline.py(6 tunables),thermodynamics.py,retrieval_dispatch.py: these constants used to be captured as function-default-parameter values (frozen at module-def/import time). Changed defaults toNonewith a resolve-once-lazily-and-cache-forever helper per module, avoiding an import-order hazard. No test or benchmark ever overrides these vars after process start, so this is behaviorally identical to "frozen at import."thermodynamics.pyalso preserves the original fail-fast parsing (no try/except aroundfloat()).retrieval_dispatch.py's publicUNTRUSTED_ORIGIN_FACTORconstant became a functionuntrusted_origin_factor(); updated its two other call sites.reconsolidation.py:os.path.dirnamewas pure (no I/O) — replaced with a local_posix_dirname()pinned equal toposixpath.dirnameby a new test.reranker_model.py/reranker.py/ newmcp_server/infrastructure/reranker_cache.py: the real filesystem I/O (cache-dir resolution, model-file existence check, sha256 of the on-disk weights) moved to the new infrastructure module;reranker_model.pykeeps only pure path-string composition plus three injected providers. Function/attribute names are unchanged becausebenchmarks/reranker_matrix/runtime.py's cell-pinning system monkeypatches them by name directly for reproducibility verification.reranker_cache_dir()/_model_path()now returnstrinstead ofPath. Benchmarks are their own composition root, so 4 benchmark entry points needed the same wiring — factored intobenchmarks/lib/_reranker_wiring.py.telemetry.py:_LOG_PATHused to duplicate the exact$CORTEX_CLAUDE_DIRresolution thatmcp_server/shared/log_rotation.methodology_log_path()already provides — replaced with a direct call. Also deleted the eager mkdir-at-import (open_rotating_log()already creates the parent directory on every write); fixed the one test that relied on the eager side effect's timing.Pruned exactly the 11 now-stale
layer-violationbaseline entries for these 9 files.Known limitation (documented, not a regression from before this PR): about 13 hook scripts that never import
mcp_server.hooks._telemetrydon't getcore/environment.py's reader wired, so an env var likeCORTEX_TELEMETRY_DISABLEDorCORTEX_ABLATE_*silently falls back to "not disabled" if set for just one of those hook subprocesses in isolation. This exact same "not wired in every hook" gap already existed pre-#560 forwiki_axis_registry.configure_default_wiki_rootandwiki_classifier.configure_user_rules_provider— not a regression this PR introduces, and no existing test requires the wider wiring.Test plan
python scripts/check_craftsmanship.py --base origin/mainreturns OKruff check .andruff format --check .are cleanpyright mcp_server/reports 0 errorspytest -qwith--extra dev,sqlite,postgresql: 8438 passed, 165 skipped, 0 failed🤖 Generated with Claude Code
Fixes #560