Originally created by: fu351
Add an import-linter contract that keeps the objective-rules package free of the subjective layer's ML import chain, so the host-hook hot path can never silently regress.
Host hooks (Claude Code / Codex adapters) build the objective rule set on every tool call, in a cold-start CLI process. That path must not import numpy/scipy/river. Today doberman.engine.rules stays clean by convention: e.g. PR [#323] deliberately extracted trifecta_fires into a models-only leaf (doberman.engine.trifecta) precisely so engine.rules.trifecta_floor wouldn't pull doberman.engine.subjective (→ engine.detectors/engine.registry → river/numpy/scipy).
Nothing in CI enforces this. A future rule that does from doberman.engine.subjective import ... (or otherwise reaches the ML chain) would add ~2s of import cost to every tool call, and review is the only thing that would catch it.
An import-linter forbidden contract in pyproject.toml:
source_modules = ["doberman.engine.rules"] (and doberman.engine.trifecta, doberman.engine.objective)forbidden_modules = ["doberman.engine.subjective", "doberman.engine.detectors", "numpy", "scipy", "river"]Then verify lint-imports stays green (it should — the code already respects this).
objective.py may legitimately need something — check before finalizing the source list).
Ticket changed by: fu351