docs(openspec): final-review rulings — claim-all scope, per-record errors, fixtures ignore, hardening
Refs #1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
This commit is contained in:
parent
1b23554658
commit
968140f7e1
@ -75,7 +75,7 @@ interface Env { now(): Date; random(): number; deviceId: string; }
|
||||
|
||||
### Ручные команды
|
||||
|
||||
`claimAll()`: для каждой записи из `claimable()` одной записью `voice-device := текущее`, `voice-status := saved`, удалить `voice-next-attempt` и `voice-sent-at`; `voice-attempts` сохраняется. Затем `tick()`. `retry(notePath)`: только из `failed`/`retry` → `saved`, `voice-attempts := 0`, удалить `voice-next-attempt`/`voice-error`; затем `tick()`.
|
||||
`claimAll()`: для каждой записи из `claimable()` одной записью `voice-device := текущее`, `voice-status := saved`, удалить `voice-next-attempt` и `voice-sent-at`; `voice-attempts` сохраняется. Собственные записи устройства в `retry` и зависшие `sent` тоже переводятся в `saved` (без `voice-next-attempt`/`voice-sent-at`, счётчик сохраняется), чтобы отправиться сразу (решение 33). Затем `tick()`. `retry(notePath)`: только из `failed`/`retry` → `saved`, `voice-attempts := 0`, удалить `voice-next-attempt`/`voice-error`; затем `tick()`.
|
||||
|
||||
### Захват
|
||||
|
||||
@ -131,3 +131,7 @@ interface Env { now(): Date; random(): number; deviceId: string; }
|
||||
30. 2026-09-27 (исполнение, контроллер) — Почти одинаковые тестовые помощники (`setup`/`rec`/`seed`/`fields`) в `tests/queue.test.ts` и `tests/queue-commands.test.ts` реализуются как в плане, без выноса в `tests/fakes.ts`. *Это небольшая тестовая обвязка, а не логика; помощники уже различаются (сигнатура `seed`, байты аудио); превентивная правка меняла бы дословный текст двух задач.* **~20 строк дублированной настройки тестов, которые надо держать в согласии; вынос позже механический.**
|
||||
31. 2026-09-27 (исполнение, контроллер) — Решения исполнителей задач дописываются ими в этот раздел в коммите задачи (продолжая нумерацию, пометка «исполнение»); рулинги контроллера — отдельными docs-коммитами с пометкой «исполнение, контроллер». *Требование глобальных ограничений плана и CLAUDE.md; задачи идут строго последовательно, конфликтов нумерации нет.* **Шум в нумерации/формате раздела, правится руками.**
|
||||
32. 2026-09-27 (исполнение, контроллер) — После `QueueRunner.dispose()` очередь больше не отправляет: `tick()` не начинает проход, цикл `do…while` и цикл отправки прерываются, `send()` выходит до записи `sent`; запрос, который был в полёте, по-прежнему завершается временной ошибкой (решение 24 не меняется). Отступление от дословного кода плана, добавлен тест. *Код плана после `dispose()` продолжал обходить готовые записи: каждой писал `sent`, вызывал провайдера с уже отменённым сигналом и тратил попытку, а также писал в vault после выгрузки плагина — это больше, чем цена «одна попытка из пяти», принятая в решении 24.* **Несколько строк защитного кода и тест, которые окажутся лишними, если обёртка никогда не вызывает `tick()` после `dispose()`; требуемое спекой поведение не теряется.**
|
||||
33. 2026-09-27 (исполнение, контроллер, финальное ревью) — «Распознать все ожидающие здесь» (`claimAll`) кроме чужих записей переводит в `saved` и собственные записи устройства в `retry` и зависшие `sent` (удаляются `voice-next-attempt`/`voice-sent-at`, счётчик сохраняется), затем `tick()` отправляет их сразу. Возвращаемое число — только переназначенные с других устройств. Тест плана изменён. *Спека: «после чего обработать очередь без ожидания времени следующей попытки»; абзац «Ручные команды» и тест плана сузили это без записанного решения; пользователь ждёт, что уйдёт всё ожидающее на этом устройстве.* **Если имелось в виду узкое поведение — свои повторы уходят до 30 минут раньше (лишний запрос на запись, без потери данных); откат — вернуть прежний `claimAll` и тест, переформулировать спеку.**
|
||||
34. 2026-09-27 (исполнение, контроллер, финальное ревью) — В проходе очереди ошибка обработки одной записи (исключение из `NoteStore.process` и т.п.) не останавливает остальные: запоминается первая ошибка, проход продолжается, в конце ошибка пробрасывается, так что `tick()` всё равно отклоняется. Ошибка `list()` по-прежнему отклоняет `tick()` сразу. *Иначе одна «сломанная» старейшая заметка блокирует все новые на каждом tick; проброс сохраняет видимость ошибки для обёртки.* **Чуть сложнее `pass()`; `retry()`/`claimAll()` могут отклониться, уже изменив свою запись, если упала обработка другой.**
|
||||
35. 2026-09-27 (исполнение, контроллер, финальное ревью) — Из `.gitignore` убрано правило `tests/fixtures/*.webm`. *Решения 9 и 25: аудиофикстуры любых поддерживаемых расширений лежат в git; правило давало бы зелёный прогон локально и красный на чистом клоне.* **Можно случайно закоммитить большой webm; иначе нулевая.**
|
||||
36. 2026-09-27 (исполнение, контроллер, финальное ревью) — Дешёвое усиление по итогам финального ревью: результат запроса записывается, только если запись всё ещё `sent` этим устройством с тем же `voice-sent-at`; после `dispose()` не пишут ни восстановление зависших `sent`, ни `retry()` (возвращает `false`), ни `claimAll()` (возвращает `0`); добавлены тесты на `sent` + `voice-sent-at` во время запроса и на `sent` в «Повторить распознавание». Путь vault в `esbuild.config.mjs`, Node-глобалы в типах `src/core` и CRLF остаются отложенными. *Каждое — несколько строк, закрывает названный крайний случай или фиксирует MUST спеки; другой волны исправлений в этой ветке не будет.* **~20 строк защит и тестов; если проверка устройства и `voice-sent-at` слишком строга — законный поздний результат своей отправки отбрасывается и запись повторяется через 10 минут (лишний запрос).**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user