diff --git a/openspec/changes/harden-hourly-sync-lifecycle/design.md b/openspec/changes/harden-hourly-sync-lifecycle/design.md index 37e32dc..a4795af 100644 --- a/openspec/changes/harden-hourly-sync-lifecycle/design.md +++ b/openspec/changes/harden-hourly-sync-lifecycle/design.md @@ -91,7 +91,14 @@ QA Analysis. 3. **Ограниченное ожидание на каждый шаг.** `settledWorks` получает per-id deadline: константа `WORK_WAIT_BOUND_MS = 15 * 60 * 1000`; истёкший id - возвращается как проблемный шаг с причиной `DEADLINE`. Управляемые часы в + возвращается как проблемный шаг с причиной `DEADLINE`. Тем же bound покрыты + и ожидания walk до появления durable-строк шагов (review-замечание, + follow-up WealthLedger/backend#78): `membership.request`/`member.done`, + `access.local` и dispatch `portfolio`/`operations`/`events.refresh` гоняются + с `WORK_WAIT_BOUND_MS` через race; истечение трактуется как проблемная + секция (как failed dispatch), для `access.local` — как закрытие + `INTERRUPTED`. Вызов не отменяется; поздняя durable-строка fenced по + `attemptId`, как любая поздняя публикация. Управляемые часы в тестах — jest fake timers, инъекция clock в production-код не вводится. RPC не отменяется; поздний результат шага сохраняется его собственной строкой — учтён ли он в итоге, решает fence и момент фиксации. diff --git a/openspec/changes/harden-hourly-sync-lifecycle/docs-impact.md b/openspec/changes/harden-hourly-sync-lifecycle/docs-impact.md index b46616a..e526f8d 100644 --- a/openspec/changes/harden-hourly-sync-lifecycle/docs-impact.md +++ b/openspec/changes/harden-hourly-sync-lifecycle/docs-impact.md @@ -14,6 +14,9 @@ Durable docs update нужен ограниченно: наблюдаемая с | update | `docs/architecture/cross-cutting/data-freshness.md` | cross-cutting | Рядом со словарём `lastAttempt` (`none`, `running`, `succeeded`, `partial`, `failed`): итог попытки выводится из фактических результатов её шагов; попытка, не завершившая обязательный шаг, не обозначается полным успехом; ожидание шага ограничено, зависший шаг учитывается как проблемный; попытка, потерявшая выполнение (сбой сохранения, остановка процесса), закрывается частичным успехом либо неуспехом и не блокирует следующий обход дольше обычного срока | System Analysis — Data and State Semantics, Error and Recovery Semantics; Design 1–5 | Страница не противоречит canonical spec `hourly-investment-sync` и фактическому поведению `meta` | | update | `docs/integrations/tbank.md` | integration | В разделе «Состояние и ошибки»: диагностические причины жизненного цикла попытки (`INTERRUPTED` — прервана до нормального завершения, `DEADLINE` — истечение ожидания шага) — внутренняя диагностика, не ошибки T-Bank; в hourly-read наружу не попадают, начатые обращения к T-Bank не отменяются | System Analysis — Observability Semantics; Design 3, 6 | Раздел различает ошибки подключения/external-коды и внутренние причины жизненного цикла | +PR реализации: WealthLedger/docs#37 (open) — обе страницы обновлены, diff +соответствует таблице выше (задачи 6.1 и 6.2 верифицируемы по нему). + ## Diagram Promotion Не переносить. Sequence-диаграммы (`hourly-attempt-terminal-barrier.mmd`, diff --git a/openspec/changes/harden-hourly-sync-lifecycle/tasks.md b/openspec/changes/harden-hourly-sync-lifecycle/tasks.md index 4ee41ee..88686ca 100644 --- a/openspec/changes/harden-hourly-sync-lifecycle/tasks.md +++ b/openspec/changes/harden-hourly-sync-lifecycle/tasks.md @@ -42,6 +42,17 @@ - **Verification:** SQLite-тест перезапуска процесса: брошенная попытка закрыта `partial`/`failed` с сохранёнными результатами шагов, новый обход не ранее следующего часового срока, перекрытия нет - **Depends on:** 1.1, 1.2 +- [x] 2.4 [backend] ожидания walk до durable-строк шагов + (`membership.request`/`member.done`, `access.local`, dispatch + `portfolio`/`operations`/`events.refresh`, post-wait `events.get`) + ограничены тем же `WORK_WAIT_BOUND_MS` через race; истечение — проблемная + секция либо `INTERRUPTED`-закрытие без отмены вызова + (WealthLedger/backend#78) + - **Covers:** `hourly-investment-sync` — «Каждая попытка обхода достигает итога в ограниченное время» + - **Source:** Design — Decision 3; review specs#33 (CRITICAL) + - **Verification:** SQLite-тесты с никогда не завершающимися dispatch/membership/`done`/`get`: попытка терминальна в ограниченное время, поздние вызовы не отменяются + - **Depends on:** 2.1 + ## 3. Финализаторы шагов - [x] 3.1 [backend] внешний catch финализаторов шагов (enrichment, operations