mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-22 16:25:58 +00:00
fix(config): allow underscore-prefixed internal/test keys past schema validation
The schema validation added in this PR (#34250) rejected underscore- prefixed config keys like '_test.shim_marker', breaking the Docker privilege-drop test suite (tests/docker/test_docker_exec_privilege_drop.py) which writes such markers via 'hermes config set _test.<marker> 1' to probe config.yaml file ownership after the UID-drop shim runs. Ten Docker tests failed in build-amd64 CI for this reason: test_shim_drops_root_to_hermes_uid (_test.shim_marker) test_shim_short_circuits_for_non_root (_test.shim_short_circuit) test_shim_opt_out_keeps_root (_test.opt_out) test_shim_opt_out_strict_truthiness[*] (_test.falsy) x6 test_e2e_login_then_supervised_gateway (_test.e2e_marker) Fix: treat a leading underscore on the TOP-LEVEL segment as an internal/test marker that bypasses schema validation. Mirrors Python's own '_private' convention. The escape is narrow: - Only the first segment is checked, so a genuine typo in a sub-key under a known top-level key (e.g. 'agent._max_turns') is still flagged. - Real typos ('agent.max_turn' -> 'agent.max_turns') still caught. - The headline #34067 bug ('gateway.discord.gateway_restart_notification') still caught. Tests (5 new in TestValidateConfigKey): - 4 parametrized cases for accepted underscore-prefixed keys (_test.shim_marker, _internal, _test.nested.deep.marker, _x) - test_underscore_only_first_segment_escapes: confirms agent._max_turns (underscore in a SUB-key, not the top) is still rejected. All 58 tests in test_set_config_value.py pass. Refs: #34067 #34250 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
fd19e8bb48
commit
477274f1d9
2 changed files with 36 additions and 0 deletions
|
|
@ -8645,6 +8645,20 @@ def _validate_config_key(key: str) -> tuple[bool, Optional[str]]:
|
|||
|
||||
segments = key.split(".")
|
||||
top = segments[0]
|
||||
|
||||
# ── Underscore-prefixed keys are internal/test markers ───────────
|
||||
# A leading underscore on the top-level segment (e.g. ``_test.shim_marker``)
|
||||
# signals an intentionally non-schema, internal key. Test harnesses and
|
||||
# tooling use these to write a deterministic marker into config.yaml
|
||||
# without polluting the user-facing schema (see the Docker privilege-drop
|
||||
# shim test, which writes ``_test.shim_marker`` to probe file ownership).
|
||||
# Python's own convention treats a leading underscore as "private"; we
|
||||
# honour that here so schema validation never blocks deliberately-internal
|
||||
# keys. This is narrow: only the FIRST segment is checked, so a real typo
|
||||
# like ``agent._max_turns`` still gets caught at the sub-key level.
|
||||
if top.startswith("_"):
|
||||
return True, None
|
||||
|
||||
known = _known_top_level_keys()
|
||||
|
||||
# ── First-segment validation ─────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -587,3 +587,25 @@ class TestValidateConfigKey:
|
|||
if expected_in_suggestion is not None:
|
||||
assert suggestion is not None and expected_in_suggestion in suggestion, \
|
||||
f"Expected suggestion to contain {expected_in_suggestion!r}, got {suggestion!r}"
|
||||
|
||||
@pytest.mark.parametrize("key", [
|
||||
"_test.shim_marker",
|
||||
"_internal",
|
||||
"_test.nested.deep.marker",
|
||||
"_x",
|
||||
])
|
||||
def test_underscore_prefixed_keys_are_accepted(self, key):
|
||||
"""Underscore-prefixed top-level keys are internal/test markers and
|
||||
bypass schema validation. The Docker privilege-drop shim test writes
|
||||
``_test.shim_marker`` to probe config.yaml ownership; that must not
|
||||
be rejected. (Regression: #34250 schema validation broke this.)"""
|
||||
from hermes_cli.config import _validate_config_key
|
||||
is_known, _ = _validate_config_key(key)
|
||||
assert is_known, f"Expected underscore-prefixed {key!r} to be accepted"
|
||||
|
||||
def test_underscore_only_first_segment_escapes(self):
|
||||
"""The underscore escape only applies to the FIRST segment. A real
|
||||
typo in a sub-key (e.g. agent._max_turns) is still caught."""
|
||||
from hermes_cli.config import _validate_config_key
|
||||
is_known, suggestion = _validate_config_key("agent._max_turns")
|
||||
assert not is_known, "Sub-key typo under a known top-level key must still be flagged"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue