* feat: expose msg_limit ceiling via /api/session metadata, frontend reads dynamically (#6177) Backend exposes _MAX_MSG_LIMIT as _msg_limit_max in every /api/session response. Frontend reads it dynamically, falling back to _MSG_LIMIT_MAX for older servers. This removes the hand-mirrored coupling between the two layers. Removed test_msg_limit_ceiling_drift.py since the mirror pattern that required the drift guard is replaced by dynamic metadata. This is the standalone metadata-decoupling piece from #6206, without the clamp/paging that already shipped in exp-v0.52.98 via #6152/#6154. * fix(session): declare _msgLimitMax at module scope + CHANGELOG + gate fixes (#6214 follow-up) The submitted PR used _msgLimitMax at two read sites (boundedReloadLimit in _ensureMessagesLoaded, useBeforePaging in _loadOlderMessages) but never declared it and read it before assignment -> undefined on cold load -> full-transcript fetch every load (regression) + implicit global. Declared `let _msgLimitMax = _MSG_LIMIT_MAX;` at module scope so the reload-width paths always read a defined value (the static fallback) until the server's _msg_limit_max lands. Also: defined the ceiling globals in the two inline node-harness tests that copy _ensureMessagesLoaded's body (test_cross_session_message_load_isolation, test_session_unread_dot_on_visit), updated the source-string assertion in test_webui_external_refresh_frontend, and added 3 decoupling tests (backend field present, module-scope declaration + fallback, both paths read the live ceiling) replacing the deleted drift-guard. Gate: Codex adversarial SAFE TO SHIP (executable probes: cold-load fallback, mixed-version omission, live update, cross-session isolation, over-ceiling bare refresh, msg_before row preservation). Full sharded suite green. Co-authored-by: webtecnica <webtecnica@users.noreply.github.com> --------- Co-authored-by: webtecnica <webtecnica@users.noreply.github.com> Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
This commit is contained in:
8 files changed
+58
-79
No files matched your search
@@ -64,3 +64,34 @@ def test_parse_msg_limit_zero_and_negative_clamp_to_one():
|
||||
for msg_limit=0 gets a 1-row window, not the full transcript."""
|
||||
assert _parse_msg_limit("0") == 1
|
||||
assert _parse_msg_limit("-5") == 1
|
||||
|
||||
|
||||
# ── #6177: metadata-decoupling — the frontend reads the ceiling from the
|
||||
# /api/session `_msg_limit_max` field instead of a hand-mirrored constant. ──
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
_ROUTES_SRC = (Path(__file__).resolve().parents[1] / "api" / "routes.py").read_text(encoding="utf-8")
|
||||
_SESSIONS_JS = (Path(__file__).resolve().parents[1] / "static" / "sessions.js").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_backend_exposes_msg_limit_max_in_session_response():
|
||||
"""The /api/session handler advertises the ceiling as `_msg_limit_max` so the
|
||||
frontend never has to hand-mirror _MAX_MSG_LIMIT (#6177 decoupling)."""
|
||||
assert 'raw["_msg_limit_max"] = _MAX_MSG_LIMIT' in _ROUTES_SRC
|
||||
|
||||
|
||||
def test_frontend_declares_live_ceiling_at_module_scope_with_fallback():
|
||||
"""`_msgLimitMax` MUST be declared at module scope (not an implicit global)
|
||||
with the static fallback, so the reload-width paths read a DEFINED value
|
||||
before the first /api/session response lands — otherwise a cold load reads
|
||||
`undefined`, drops msg_limit, and full-loads every session."""
|
||||
assert "let _msgLimitMax = _MSG_LIMIT_MAX;" in _SESSIONS_JS
|
||||
# refreshed from the response metadata, falling back when the server omits it
|
||||
assert "_msgLimitMax = data.session._msg_limit_max || _MSG_LIMIT_MAX;" in _SESSIONS_JS
|
||||
|
||||
|
||||
def test_frontend_reload_width_paths_read_the_live_ceiling():
|
||||
"""Both reload-width decisions read the live `_msgLimitMax`, not the mirror."""
|
||||
assert "reloadLimit <= _msgLimitMax" in _SESSIONS_JS # _ensureMessagesLoaded
|
||||
assert "requestedLimit >= _msgLimitMax" in _SESSIONS_JS # _loadOlderMessages
|
||||
Reference in new issue
Block a user