"""The Settings UI shows the default the server actually uses (#3927). WHY THIS EXISTS A retrieval threshold lives in two places by necessity: a Python constant the arm reads when no row is stored, and a Vue `ref` the Settings form shows when the operator has never touched it. Neither can import the other. So the form's initial value is a CLAIM about the server's behaviour, and it is the kind of claim that rots quietly. Retune the Python constant and the input keeps rendering the old number — the operator reads it as the bar in force, sees no reason to change anything, and the form has misinformed them about the one fact it exists to convey. Nothing errors, nothing looks wrong, and the value they are shown is simply not the value being applied. WHAT THIS PINS The RELATIONSHIP, never the number: for each threshold, the Vue ref's initial string equals the Python default. Retuning either stays free as long as both move — which is the point, because these are tuning values and #3853 moved one of them the day this was written. Both sides are read from SOURCE rather than imported. The Vue file cannot be imported at all, and reading the Python constant through an import would tie this to module-load side effects it has no interest in. It cannot check that the form WRITES the right key — that is behaviour, and the keys are asserted where they are built. It catches the drift that has no other alarm. """ from __future__ import annotations import pathlib import re import pytest ROOT = pathlib.Path(__file__).resolve().parents[1] _PY = ROOT / "src" / "scribe" / "services" / "plugin_context.py" _VUE = ROOT / "frontend" / "src" / "views" / "SettingsView.vue" # (python constant, vue ref). Hand-written because the pairing is an editorial # fact — the names do not share a convention either side could derive — but # every entry is asserted to EXIST on both sides, so a rename fails loudly # here rather than silently dropping that threshold from the check. _PAIRS = ( ("AUTOINJECT_DEFAULT_THRESHOLD", "kbInjectThreshold"), ("WRITEPATH_DEFAULT_THRESHOLD", "kbWritePathThreshold"), ("RULEHINT_DEFAULT_THRESHOLD", "kbRuleHintThreshold"), ("TOOLRULE_DEFAULT_THRESHOLD", "kbToolRuleThreshold"), ("PROMPTRULE_DEFAULT_THRESHOLD", "kbPromptRuleThreshold"), ) def _python_default(name: str) -> float: m = re.search(rf"^{re.escape(name)}\s*=\s*([0-9.]+)\s*$", _PY.read_text(), re.M) assert m, ( f"{name} is no longer a bare module-level float in " f"services/plugin_context.py. If it moved or was renamed, update " f"_PAIRS; if it was retired, drop its row — leaving it here checks " f"nothing while looking like coverage." ) return float(m.group(1)) def _vue_default(ref_name: str) -> float: m = re.search(rf"const {re.escape(ref_name)} = ref\(\"([0-9.]+)\"\)", _VUE.read_text()) assert m, ( f"{ref_name} is no longer a `ref(\"\")` in SettingsView.vue. " f"If the control was renamed, update _PAIRS; if it was removed, the " f"setting has lost its UI and that is the thing to fix (rule 25)." ) return float(m.group(1)) @pytest.mark.parametrize(("constant", "ref_name"), _PAIRS, ids=[p[0] for p in _PAIRS]) def test_the_form_shows_the_default_the_server_uses(constant, ref_name): """An untouched control must render the bar actually in force.""" server, form = _python_default(constant), _vue_default(ref_name) assert form == server, ( f"SettingsView shows {form} for {ref_name} while the server defaults " f"to {server} ({constant}). An operator who has never set this reads " f"the form as the value in force, so the two must move together — " f"retune both, or neither." )