mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-30 19:09:28 +00:00
fix: floor gate only refuses configs with an EXPLICIT below-floor _config_version
Profile clones and hand-written minimal configs carry no _config_version key; check_config_version() coerces that to 0, which wrongly tripped the v12 floor and left clones unstamped (caught by CI: test_clone_config_copies_files / test_clone_from_named_profile). Version-less configs now take the normal ladder + fresh stamp — the historical behavior; only genuinely ancient explicit-version configs are refused.
This commit is contained in:
parent
4b33e5663b
commit
4ae5efa3f4
1 changed files with 40 additions and 8 deletions
|
|
@ -1781,6 +1781,25 @@ def _coerce_config_version(value: Any) -> int:
|
|||
return max(version, 0)
|
||||
|
||||
|
||||
def _raw_config_has_explicit_version() -> bool:
|
||||
"""True when config.yaml exists, parses, and carries a ``_config_version`` key.
|
||||
|
||||
Distinguishes an ANCIENT config (explicit old version → refused by the
|
||||
v12 support floor) from a fresh minimal/hand-written/cloned config with
|
||||
no version key at all (→ migrated + stamped normally). Missing or
|
||||
unparseable files return False so they never trip the floor gate.
|
||||
"""
|
||||
config_path = get_config_path()
|
||||
if not config_path.exists():
|
||||
return False
|
||||
try:
|
||||
with open(config_path, encoding="utf-8") as f:
|
||||
raw = fast_safe_load(f) or {}
|
||||
except Exception:
|
||||
return False
|
||||
return isinstance(raw, dict) and "_config_version" in raw
|
||||
|
||||
|
||||
def check_config_version() -> Tuple[int, int]:
|
||||
"""
|
||||
Check the raw on-disk config schema version.
|
||||
|
|
@ -2142,20 +2161,33 @@ def migrate_config(interactive: bool = True, quiet: bool = False) -> Dict[str, A
|
|||
current_ver, latest_ver = check_config_version()
|
||||
|
||||
# ── Auto-migration support floor (policy: v12, July 2026) ──
|
||||
# A config below the floor is NOT auto-migrated and NOT rewritten: we
|
||||
# surface a clear, actionable message and leave the file byte-for-byte
|
||||
# untouched. This matches the fail-safe posture for unparseable configs
|
||||
# (warn on stderr, continue — load_config() deep-merges defaults at read
|
||||
# time), so the CLI never crashes on an ancient config. The floor gate
|
||||
# lives here in the wrapper (not in run_migrations) so the registry
|
||||
# driver stays a pure mechanism that tests can exercise directly.
|
||||
# A config with an EXPLICIT on-disk ``_config_version`` below the floor is
|
||||
# NOT auto-migrated and NOT rewritten: we surface a clear, actionable
|
||||
# message and leave the file byte-for-byte untouched. This matches the
|
||||
# fail-safe posture for unparseable configs (warn on stderr, continue —
|
||||
# load_config() deep-merges defaults at read time), so the CLI never
|
||||
# crashes on an ancient config. The floor gate lives here in the wrapper
|
||||
# (not in run_migrations) so the registry driver stays a pure mechanism
|
||||
# that tests can exercise directly.
|
||||
#
|
||||
# A config with NO ``_config_version`` key at all is NOT floor-refused:
|
||||
# that shape is a fresh minimal config (profile clones write bare keys;
|
||||
# users hand-write two-line configs), not an ancient install. Those get
|
||||
# the normal ladder (the retired <12 steps were no-ops for configs
|
||||
# lacking the legacy keys they migrated) and a fresh version stamp —
|
||||
# the historical behavior.
|
||||
from hermes_cli.config_migrations import (
|
||||
SUPPORT_FLOOR_VERSION,
|
||||
run_migrations,
|
||||
support_floor_message,
|
||||
)
|
||||
|
||||
floor_refused = current_ver < SUPPORT_FLOOR_VERSION and current_ver < latest_ver
|
||||
_explicit_version = _raw_config_has_explicit_version()
|
||||
floor_refused = (
|
||||
_explicit_version
|
||||
and current_ver < SUPPORT_FLOOR_VERSION
|
||||
and current_ver < latest_ver
|
||||
)
|
||||
if floor_refused:
|
||||
msg = support_floor_message()
|
||||
results["warnings"].append(msg)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue