fix(tui-gateway): count live rows in the 4033 archived_messages on a carrier cut

Gate C18 r1 quality [Low, unverified -> reproduced]: on the
durable-carrier path `truncated` is the physical durable_prefix, so
`len(history) - len(truncated)` mixed live and physical rows. A probe
with target row 101 absorbed into a repaired live carrier reported
archived_messages=5 for a cut that drops all 6 live rows (the carrier
and everything after it). The refusal now counts from the live cut
index on that path; the plain path is unchanged.
This commit is contained in:
kshitijk4poor
2026-10-06 13:15:03 +05:30
committed by kshitij
parent 9c98cc19f6
commit b8eedfefa2
2 changed files with 14 additions and 1 deletions

View File

@@ -51,6 +51,17 @@ def test_prompt_submit_refuses_deep_truncation_without_confirm(monkeypatch):
assert _submit(confirm_deep_truncate=True).get("error") is None
assert replaced == [history[:2]]
# Durable-carrier cut: the target (101) was absorbed into a repaired live carrier;
# the refusal counts live rows from the carrier on, never live minus physical.
physical = [{"_row_id": 100, "role": "user", "content": "u0"},
{"_row_id": 101, "role": "user", "content": "u0b"}, *history[1:]]
_FakeDB.get_messages_as_conversation = lambda self, key, **_kw: [dict(m) for m in physical] # type: ignore[attr-defined]
sess["running"] = False # the confirmed submit above left a (never-started) turn
sess["history"] = [{"_row_id": 100, "_absorbed_row_ids": [101], "role": "user",
"content": "u0\n\nu0b"}, *history[1:]]
carrier = _submit(truncate_before_row_id=101)
assert carrier["error"]["data"] == {"archived_messages": 6, "archived_user_turns": 3}
finally:
server._sessions.pop("deep-trunc-sid", None)

View File

@@ -466,7 +466,9 @@ def _truncate_history_for_submit(rid, sid, session, params, requested_rebind_ids
# drop exactly one user turn, deeper cuts need confirm_deep_truncate.
archived_user_turns = user_turn_count - ordinal
if archived_user_turns > 1 and not is_truthy_value(params.get("confirm_deep_truncate")):
archived_messages = len(history) - len(truncated)
# A durable-carrier cut's ``truncated`` is physical rows: count the live cut instead.
archived_messages = len(history) - (
cut_index if durable_prefix is not None else len(truncated))
logger.warning(
"prompt.submit: REFUSED deep truncation of session %s (%d messages / %d user "
"turns would be archived; ordinal=%d).",