WEB-358 · Задача · billing · web
QIMPL-2: уникальный locked charge-subject fence до T3/send — одна reservation не авторизует два job
Закрыт
P1 · важно
ведёт: —
Суть
Из qreview7 §5.2: ввести до T3/send уникальный locked charge-subject fence (reservation/hold/slot → ровно один job/provider attempt), проверять на каждом T3 repeat и send fence. Закрывает double-authorize класс. Контракт: WEB094-QUEUE-DESIGN-v7.md (ЗАМОРОЖЕН как дизайн-контракт 25.08 по решению owner «v7 последний дизайн-раунд»). Блокер из qreview7-sol-report.md (A1), закрывать КОДОМ с приёмкой: негатив-тест обязателен, приёмщик ≠ автор, исполнимый SQL-прогон в чистой схеме как в ревизии.
Доказательства
[25.08 ~15:20] Взято волной qimpl2 (luna xhigh, wt-qimpl2 от головы qimpl1): уникальный locked charge-subject fence до T3/send (одна reservation ≠ два job), негатив на второй job + конкурентный идемпотентный повтор, доказательство psql-ом.
[25.08 ~16:20Z] СДЕЛАНО волной qimpl2: commit 5da4682. Fence: таблица queue_charge_subject_fence (PK reservation_id, uq job/operation/slot) + partial-uq на provider_dispatch_attempt(reservation_id) + queue_assert_charge_subject_fence() с row-lock и атомарным claim (чужой owner → CHARGE_SUBJECT_FENCE_CONFLICT); вызовы на T3, T3-repeat и send fence. Create-pass чистой схемы rc=0. §5.3-5.5 не заявлены. → review.
📎 Трейл: отчёт /home/ubuntu/waves/QIMPL2-REPORT.md; ветка qimpl2@5da4682 (в проде 54, merge ce4aa0c). Файлы: prisma/queue-v7/001-schema.sql, 010-helpers.sql, 030-t3.sql.
[2026-08-25 19:11Z] Независимая приёмка запущена: волна accqimpl на A1 (sol xhigh, приёмщик≠автор), worktree от прод-коммита a453b16; обязательны негативные тесты новых классов; для не-влитых тикетов волна установит факт NOT-LANDED. Бриф /home/ubuntu/waves/accqimpl-brief.md, отчёт будет в ACCQIMPL-REPORT.md.
[2026-08-25 20:05Z] ПРИНЯТО (accqimpl, приёмщик≠автор, одноразовый Postgres, новые негатив-классы: гонка двух job за reservation / underflow-откат / повторный late receipt / повреждённый committed slot). GO → done. Отчёт A1:ACCQIMPL-REPORT.md.
Починено в
a453b16
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-358","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-25T19:57:41.135Z