fix(gateway): a translated intentional-silence sentinel is still silence

A model lane that does not think in English answers the cron instruction
("respond with exactly [SILENT]") by translating the sentinel rather than
dropping it. LIVE_GATEWAY_SILENT_MARKERS is English-only, so the whole control
token is delivered to the user as content. Carry the zh-Hans forms (the only
non-English locale this project documents) and derive the autonomous lane's
bracketed-prefix rule from the set so the two rules cannot drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oAAQ4T859Y8fWNXRoiNEB
This commit is contained in:
Todd Dailey
2026-09-14 07:41:35 -07:00
committed by Teknium
parent 4db4650a01
commit 623eb48f2f
2 changed files with 40 additions and 3 deletions
+17 -3
View File
@@ -11,8 +11,22 @@ from typing import Any
# Exact whole-response markers meaning "the agent intentionally chose not to
# reply". Keep small and explicit; arbitrary empty output remains an
# error/empty-response path, not silence.
LIVE_GATEWAY_SILENT_MARKERS = frozenset({"[SILENT]", "SILENT", "NO_REPLY", "NO REPLY"})
# error/empty-response path, not silence. A lane that does not think in English
# translates the sentinel rather than dropping it, and the whole control token
# then reaches the user as content, so the translated forms are carried here
# too. zh-Hans is the only non-English locale this project ships documentation
# for, which is where the list stops.
LIVE_GATEWAY_SILENT_MARKERS = frozenset({
"[SILENT]", "SILENT", "NO_REPLY", "NO REPLY",
"[静默]", "静默", "[沉默]", "沉默",
})
# Bracketed markers drive the autonomous lane's prefix rule ("[SILENT] nothing
# new this tick"). Derived from the set above so a new marker cannot be added to
# one rule and forgotten in the other.
_BRACKETED_SILENCE_MARKERS = tuple(
sorted(m for m in LIVE_GATEWAY_SILENT_MARKERS if m.startswith("["))
)
# The persisted user-row kind of a self-injected MessageEvent(internal=True) turn — the only
# machinery kind the gateway produces; only these may vanish on a bare silence marker.
@@ -75,7 +89,7 @@ def is_autonomous_silence_response(response: Any) -> bool:
return False
lines = [ln for ln in stripped.splitlines() if ln.strip()]
# Bracketed form only for the prefix rule, so a bare "Silent retry succeeded" is NOT swallowed.
return stripped.upper().startswith("[SILENT]") or any(
return stripped.upper().startswith(_BRACKETED_SILENCE_MARKERS) or any(
_canonical_silence_candidate(c) in LIVE_GATEWAY_SILENT_MARKERS for c in (stripped, lines[0], lines[-1])
)
+23
View File
@@ -19,3 +19,26 @@ def test_autonomous_silence_accepts_marker_with_own_line_note():
assert is_autonomous_silence_response("[SILENT] No changes detected")
def test_translated_sentinel_suppresses_delivery():
"""Regression: a non-English lane answers the silence instruction in its own language.
2026-09-14 — a deepseek cron lane had nothing to report and answered the cron
instruction ("respond with exactly [SILENT]") with "[静默]". The control token
was not a known marker, so the whole token was delivered to the user's DM as
content.
"""
assert is_intentional_silence_response("[静默]")
assert is_autonomous_silence_response("[静默]")
def test_translated_sentinel_takes_the_same_forms_as_the_english_one():
"""Same loose rule: own-line note, reordered lines, bracketless; the exact rule strips punctuation."""
assert is_autonomous_silence_response("[静默]\n\nNothing new this tick.")
assert is_autonomous_silence_response("2 deals filtered\n\n[沉默]")
assert is_autonomous_silence_response("静默")
assert is_intentional_silence_response("**沉默**")
def test_prose_mentioning_the_translated_sentinel_is_delivered():
assert not is_intentional_silence_response("status: 静默 means the lane is quiet")
assert not is_autonomous_silence_response("the lane said 静默 mid-sentence and kept talking")