From fe295aa73ab5bc9d826067892930b7161fb4f1b9 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Mon, 12 Oct 2026 22:41:23 +0300 Subject: [PATCH] spec: archive harden-hourly-sync-lifecycle change (WealthLedger/backend#56) --- .../.openspec.yaml | 0 .../design.md | 0 .../docs-impact.md | 0 .../proposal.md | 0 .../qa-analysis.md | 0 .../specs/hourly-investment-sync/spec.md | 0 .../system-analysis/analysis.md | 0 .../hourly-attempt-terminal-barrier.mmd | 0 .../sequences/hourly-bounded-wait.mmd | 0 .../sequences/hourly-recovery.mmd | 0 .../tasks.md | 0 openspec/specs/hourly-investment-sync/spec.md | 43 ++++++++++++++++++- 12 files changed, 42 insertions(+), 1 deletion(-) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/.openspec.yaml (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/design.md (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/docs-impact.md (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/proposal.md (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/qa-analysis.md (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/specs/hourly-investment-sync/spec.md (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/system-analysis/analysis.md (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/system-analysis/sequences/hourly-attempt-terminal-barrier.mmd (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/system-analysis/sequences/hourly-bounded-wait.mmd (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/system-analysis/sequences/hourly-recovery.mmd (100%) rename openspec/changes/{harden-hourly-sync-lifecycle => archive/2026-10-12-harden-hourly-sync-lifecycle}/tasks.md (100%) diff --git a/openspec/changes/harden-hourly-sync-lifecycle/.openspec.yaml b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/.openspec.yaml similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/.openspec.yaml rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/.openspec.yaml diff --git a/openspec/changes/harden-hourly-sync-lifecycle/design.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/design.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/design.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/design.md diff --git a/openspec/changes/harden-hourly-sync-lifecycle/docs-impact.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/docs-impact.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/docs-impact.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/docs-impact.md diff --git a/openspec/changes/harden-hourly-sync-lifecycle/proposal.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/proposal.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/proposal.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/proposal.md diff --git a/openspec/changes/harden-hourly-sync-lifecycle/qa-analysis.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/qa-analysis.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/qa-analysis.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/qa-analysis.md diff --git a/openspec/changes/harden-hourly-sync-lifecycle/specs/hourly-investment-sync/spec.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/specs/hourly-investment-sync/spec.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/specs/hourly-investment-sync/spec.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/specs/hourly-investment-sync/spec.md diff --git a/openspec/changes/harden-hourly-sync-lifecycle/system-analysis/analysis.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/analysis.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/system-analysis/analysis.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/analysis.md diff --git a/openspec/changes/harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-attempt-terminal-barrier.mmd b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-attempt-terminal-barrier.mmd similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-attempt-terminal-barrier.mmd rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-attempt-terminal-barrier.mmd diff --git a/openspec/changes/harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-bounded-wait.mmd b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-bounded-wait.mmd similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-bounded-wait.mmd rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-bounded-wait.mmd diff --git a/openspec/changes/harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-recovery.mmd b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-recovery.mmd similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-recovery.mmd rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/system-analysis/sequences/hourly-recovery.mmd diff --git a/openspec/changes/harden-hourly-sync-lifecycle/tasks.md b/openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/tasks.md similarity index 100% rename from openspec/changes/harden-hourly-sync-lifecycle/tasks.md rename to openspec/changes/archive/2026-10-12-harden-hourly-sync-lifecycle/tasks.md diff --git a/openspec/specs/hourly-investment-sync/spec.md b/openspec/specs/hourly-investment-sync/spec.md index 09d268e..848f981 100644 --- a/openspec/specs/hourly-investment-sync/spec.md +++ b/openspec/specs/hourly-investment-sync/spec.md @@ -25,7 +25,7 @@ - **THEN** система не запускает обход в 11:00 и может начать следующий не ранее 12:00 ### Requirement: Последний результат обхода доступен только для наблюдения -Система SHALL предоставлять авторизованному User результат последнего обхода только в границе его текущего подключения: время начала, состояние выполнения, полного успеха, частичного успеха либо неуспеха и безопасный перечень проблемных счетов или разделов. Это состояние MUST быть доступно в `meta` каждого затронутого resource read вместе с freshness, полнотой и доступностью его `data`. Успех одного счёта или раздела MUST сохраняться независимо от ошибки другого; ошибка MUST NOT заменять его последнее успешное состояние или время. Отсутствие состоявшейся попытки MUST отличаться от успешной попытки. Наблюдение результата MUST NOT предоставлять способ начать личную синхронизацию. +Система SHALL предоставлять авторизованному User результат последнего обхода только в границе его текущего подключения: время начала, состояние выполнения, полного успеха, частичного успеха либо неуспеха и безопасный перечень проблемных счетов или разделов. Это состояние MUST быть доступно в `meta` каждого затронутого resource read вместе с freshness, полнотой и доступностью его `data`. Успех одного счёта или раздела MUST сохраняться независимо от ошибки другого; ошибка MUST NOT заменять его последнее успешное состояние или время. Итог попытки MUST определяться фактическим результатом каждого обязательного шага обхода: попытка, не завершившая обязательный шаг, MUST обозначаться частичным успехом либо неуспехом и MUST NOT обозначаться полным успехом. Отсутствие состоявшейся попытки MUST отличаться от успешной попытки. Наблюдение результата MUST NOT предоставлять способ начать личную синхронизацию. #### Scenario: Частичный успех - **WHEN** Portfolio одного доступного счёта обновился, а другого не обновился @@ -38,3 +38,44 @@ #### Scenario: Старая граница подключения - **WHEN** User заменил либо удалил подключение и запрашивает результат прежнего обхода - **THEN** система не раскрывает результат прежней границы подключения + +#### Scenario: Сбой после частичного обновления +- **WHEN** попытка прервана ошибкой либо сбоем сохранения после обновления Portfolio одного доступного счёта +- **THEN** результат попытки обозначает частичный успех с проблемными шагами, а не полный успех, а обновлённый Portfolio сохраняется + +#### Scenario: Сбой до первого обновления +- **WHEN** попытка прервана до обновления любого обязательного шага +- **THEN** результат попытки обозначает неуспех, а не полный успех + +### Requirement: Каждая попытка обхода достигает итога в ограниченное время +Каждая начатая попытка часового обхода MUST достигать итогового состояния в ограниченное время. Ожидание завершения каждого обязательного шага MUST быть ограничено; шаг, не завершившийся в это ограничение, MUST быть учтён как проблемный, а попытка MUST быть закрыта частичным успехом либо неуспехом после того, как каждый обязательный шаг достиг терминального результата либо был учтён как проблемный. Истечение ограничения MUST NOT отменять уже начатые шаги. + +#### Scenario: Шаг не завершается +- **WHEN** обязательный шаг не покидает состояние выполнения дольше ограничения ожидания +- **THEN** шаг учитывается как проблемный, попытка закрывается частичным успехом либо неуспехом, а её состояние перестаёт быть выполняющимся + +#### Scenario: Наблюдение не ждёт без ограничения +- **WHEN** попытка не может завершиться из-за незавершённых шагов +- **THEN** наблюдение результата получает итоговое состояние в ограниченное время и не ожидает завершения бесконечно + +### Requirement: Восстановление после сбоя сохранения не блокирует последующие обходы +Если попытка осталась в состоянии выполнения после сбоя завершения шага, публикации результата либо закрытия попытки, система MUST привести её к диагностируемому итоговому состоянию: частичный успех либо неуспех с сохранёнными результатами шагов, а не полный успех. Последующий обход MUST становиться допустимым по обычному правилу срока, отсчитанному от начала этой попытки. Восстановление MUST NOT создавать перекрывающийся обход и MUST NOT повторять уже полученные результаты шагов. + +#### Scenario: Потерянное закрытие попытки +- **WHEN** закрытие попытки не сохранилось, а процесс продолжает работать +- **THEN** система закрывает попытку итогом из фактических результатов шагов, наблюдение получает итоговое состояние, а следующая допустимая попытка может стартовать + +#### Scenario: Перезапуск процесса +- **WHEN** процесс остановился после начала попытки и запускается снова +- **THEN** брошенная попытка обозначается частичным успехом либо неуспехом с сохранёнными результатами шагов, а новый обход начинается не ранее следующего часового срока от её начала + +### Requirement: Устаревшая публикация не влияет на актуальную попытку +Результат шага попытки, у которой появился преемник, MUST отклоняться как устаревший: он MUST NOT обновлять данные и MUST NOT учитываться в итоге актуальной попытки. Шаг устаревшей попытки MUST наблюдаться как устаревший относительно актуального преемника. Результат шага текущей попытки, полученный до фиксации её итога, MUST сохраняться и учитываться в этом итоге независимо от того, наступил ли он до или после истечения ограничения ожидания. + +#### Scenario: Поздняя публикация после появления преемника +- **WHEN** шаг старой попытки завершается после запуска следующей попытки +- **THEN** его результат отклоняется как устаревший, данные не обновляются, а итог актуальной попытки не меняется + +#### Scenario: Поздняя публикация до фиксации итога +- **WHEN** шаг завершился после истечения ограничения ожидания, но итог его попытки ещё не зафиксирован +- **THEN** его результат сохраняется и учитывается при выводе итога этой попытки