Назначение: наблюдение известных issue после выпуска без повторного чтения всей истории. Проверено 22.10.2026 на https://glitchtip.olvery.ru, GlitchTip 6.1.6. Это сервисный рецепт, не изменение collector или сервера.
У следующих списков нет серверных фильтров release и времени:
GET /api/0/issues/{issue_id}/events/;GET /api/0/projects/{organization_slug}/{project_slug}/events/.
Параметры release, query, start, end здесь не применяются. HTTP200, пустая выборка, наличие параметров в следующей Link-ссылке или совместимость SDK с Sentry не доказывают поддержку фильтра.
Рабочий путь — limit и штатный cursor из Link, локальные проверки release/времени. Не конструировать курсор самостоятельно. Для запроса достаточно существующего glitchtip-olv3729 через штатный helper; токен и полный ответ не выводить и не сохранять.
Пример читает одну запись известной issue, выводит только HTTP-код, release, времена и наличие следующей страницы. Это не полный observation и не доказательство исправности приложения.
/home/olvr/bin/olvr-secret run glitchtip-olv3729 -- python3 - <<'PY'
import json, os, urllib.parse, urllib.request
url = "https://glitchtip.olvery.ru/api/0/issues/29879/events/"
url += "?" + urllib.parse.urlencode({"limit": 1})
req = urllib.request.Request(url, headers={
"Authorization": "Bearer " + os.environ["OLVR_SECRET"]})
with urllib.request.urlopen(req, timeout=25) as r:
rows = json.load(r)
link = r.headers.get("Link", "")
print("http", r.status, "rows", len(rows))
for e in rows:
tags = e.get("tags") or {}
if isinstance(tags, list):
tags = {t.get("key"): t.get("value") for t in tags}
release = tags.get("release") or e.get("release")
if isinstance(release, dict):
release = release.get("version")
print({"release": release,
"dateReceived": e.get("dateReceived") or e.get("date_received"),
"dateCreated": e.get("dateCreated") or e.get("date_created")})
print("has_next", any('rel="next"' in p and 'results="true"' in p
for p in link.split(",")))
PY
Для обычного обхода используется ?limit=100. urllib.parse.urlencode кодирует query-значения; литеральный плюс в 4.6.5+9716 должен стать %2B, а не пробелом. Это правило encoding, не обещание наличия release-фильтра.
rel=«next» и results=«true»; перед передачей Authorization проверять тот же HTTPS-host glitchtip.olvery.ru и API-путь. limit=100 — размер страницы, не общий предел.dateReceived / date_received как UTC datetime. Это серверное поступление. dateCreated / date_created — время события от клиента; им нельзя заменять границу поступления.com.tpark_it.pstu@4.6.5+9716 ИЛИ app context содержит app_identifier=com.tpark_it.pstu, app_version=4.6.5, app_build=9716. Проверка только release уже этого исходного контракта. Версия/build без app identifier также недостаточны.dateReceived >= 2026-10-22T12:17:07Z. Проверять все события нужного временного диапазона, независимо от release.-id UUIDv7, что соответствует невозрастанию серверного dateReceived. На странице, пересёкшей cutoff, обработать подходящие события; когда встретилось серверное время строго меньше cutoff, более старые страницы для post-cutoff результата не нужны. Равное cutoff время включается. При отсутствующем/неразбираемом времени или нарушенном порядке не объявлять раннюю остановку полным доказательством: сохранить gap.Отсутствие событий с ошибкой не доказывает успешные сессии. List endpoint читает свой queryset; полноценность cold-storage-истории этим рецептом не обещается.
Минимальный read-only control на issue 29879, 22.10.2026 16:20:17Z:
?limit=1 → HTTP200, 1 событие: release com.tpark_it.pstu@4.6.1+7740, received 2026-10-22T08:17:55.915Z;limit=1 плюс release=jfVY-no-such-release-2099, start=2099-01-01T00:00:00Z, end=2099-01-02T00:00:00Z, query=release:«jfVY-no-such-release-2099» timestamp:>2099-01-01 → HTTP200, та же запись2026.Идентичность сравнивалась в памяти; идентификаторы и пользовательский payload не сохранялись. В отличие от пустого ответа, непустой контрпример показывает игнорирование переданных ограничений; точный набор поддержанных параметров установлен исходником.
Фактический target: srv-glitchtip.olvr, glitchtip-web-1, glitchtip/glitchtip:6, running. GLITCHTIP_VERSION=6.1.6.
sha256:8476bbdf291f946850fc6430d2cab62836918638ced34f4791593081bc067128;glitchtip/glitchtip@sha256:f45485d296697531464b4484ee9bb40a51a774df820f74128a2b2ae0c5a0b00f;/code/apps/issue_events/api/events.py:20–35,77–85,209–226: queryset ограничен доступом и issue/project; оба списка не принимают фильтры и сортируют по -id;1eae9be2df11f27cc5bbc29c24a73dce7d875be1f23c22e030507672ecb1eaac;/code/apps/issue_events/schema.py:214–219: created→timestamp, received→received;/code/apps/issue_events/models.py:308–317: received извлекается из серверного UUIDv7 с миллисекундной точностью;/code/glitchtip/api/pagination.py: AsyncLinkHeaderPagination, limit/cursor и Link. Возвращаемый Link сохраняет исходные query-параметры, но это не означает их применение.
GET /api/0/ возвращает API version 0, не версию приложения.
Evidence: Card jfVY, receipts OvtbEO, 0r9VZC, XEu7hX, 4XP9Pe. Безопасные artifacts: /home/BVNq/work/jfVY/installed-api-contract.txt, filter-controls-safe.json и соответствующие диагностические скрипты. Источник исходного observation — 3kfw/0dgUUT; его collector и принятое observation не менялись и не переаттестовывались.
После смены GlitchTip image/version сверять затронутый API-контракт заново. Доработка сервера, новый collector, runner или общий механизм фильтрации в этот рецепт не входят.