Разбор хвостов полного прогона: было 2407/2418, стало 2417/2418 — единственное
оставшееся падение ExampleTest воспроизводится только там, где не собран фронт
Vite manifest not found, к коду отношения не имеет.
1. partitions:create-months — новый флаг --behind, по умолчанию 1.
Нарезалось только «текущий месяц и вперёд», поэтому на свежей базе партиции за
прошлый месяц не было НИКОГДА. Между тем строки с датой в прошлом месяце — штатное
явление: тридцатидневное окно списаний метрика runway и вставки на стыке месяцев.
На боевом не всплывало — там партиции копятся с самого начала, проверено: нарезаны
до января 2027, крон жив. А на свежей базе и в CI INSERT падал «no partition found»
в первой половине КАЖДОГО месяца. Ловилось двумя тестами AdminTenantShowTest.runway
и роутингом лида.
2. Возвращены три аудит-теста, потерянных при сведении main 09.07.
ADR-021 сделал цепочки журналов общими и AuditChainConfig в main это уже отражает,
а тесты остались на старом per-tenant поведении ADR-018 и падали. Правильные версии
лежали на ветке fix/audit-chain-global-scope, но в main не доехали — тот же класс
потери, что и CsvReconcileJobTest.
Тесты: полный прогон 2417/2418 зелёный, Pint чисто.
Известное и НЕ тронутое, вынесено в отдельный список:
- Larastan на main даёт 30 замечаний уровня типов, ни одного живого бага:
мёртвые ветки в AuditRebuildChain, оставшиеся от ADR-021; ресурсы автоподбора без
аннотации модели; ProjectController читает виртуальные пометки gate_payload и
launch_deferred, которых нет в таблице.
- Тест лимита входов флакует только в длинном прогоне, в одиночку зелёный.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
При зелёной проверке всех партиций таблицы audit:verify-chains теперь закрывает
оставшиеся открытые инциденты разрыва hash-chain по этой таблице. Убирает класс
вечно-открытых ложных инцидентов после транзиентного разрыва — например строк
тест-тенантов приёмки, удалённых teardown.
Диагностика прогона 22.06: 4 m06-инцидента 576-579 были только по строкам
тест-тенантов; teardown их удалил, боевые цепочки tenant 2 целы.
TDD: 2 теста (целая таблица закрывает инцидент; сломанная — не трогает).
Pint и Larastan чисто, регрессий нет.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prod smoke revealed the chain is PER-RLS-SCOPE, not global: audit_chain_hash()
trigger's prev-SELECT obeys each table's RLS policy under the inserting tenant's
GUC. On dev (superuser) it sees all rows (global chain); on prod (crm_app_user)
only RLS-visible rows (per-tenant chain). tenant_operations_log false-broke at a
tenant boundary (row 32, tenant 4 after tenant 3 rows).
Fix (stakeholder choice: per-scope validator, no trigger change / no hash rebuild):
- recompute now LAG OVER (PARTITION BY <scope> ORDER BY id):
tenant_id for tenant_operations_log/activity_log/balance_transactions/pd_processing_log;
(actor_type, tenant_id) for auth_log (RLS also filters actor_type='tenant_user');
global for saas_admin_audit_log (no tenant RLS — crm_admin_user BYPASSRLS sees all).
- exit code: incident write now best-effort (try/catch); ANY breach → self::FAILURE
regardless of whether incident row could be written (no active saas_admin FK).
Tests 7/7 (+multi-tenant per-tenant regression that reproduces prod chaining,
+exit-code-without-admin). Console 21/21, pint clean, larastan 0.