Files
specs/openspec/schemas/wealth-ledger-sdd-lab/spec-writing.md
T
codex-bot b9ec11f5ba
Specs security / security (push) Successful in 8s
Specs verify / verify (push) Successful in 10s
refactor: make sdd-lab review-driven (WealthLedger/specs#66)
Replace executable schema checks with explicit review-driven readiness, add a requirement-writing profile, and incorporate review clarifications for source traceability and comparative validation.
2026-10-30 13:35:39 +03:00

243 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Spec Writing Profile
Профиль написания и ревью требований `wealth-ledger-sdd-lab`. Цель — одинаковое
понимание поведения разными авторами, разработчиками и QA, а не дословно одинаковые
документы. Это адаптация инженерных практик, не заявление о соответствии стандартам.
## Scope
Автор и reviewer читают профиль перед подготовкой или согласованием Specs. Правила
применяются к новым и изменяемым требованиям; весь canonical store ради стиля не
переписывается. Пути, delta-операции и gates задаёт `schema.yaml`.
Specs определяют наблюдаемое поведение. Обоснования и открытые решения — в Proposal,
межсистемные детали — в `analysis/`, механизмы — в design, способы доказательства —
в QA. Ни один downstream-артефакт не вводит новое поведение молча.
## Writing Rules
1. **Основание.** Каждое обязательство следует из согласованного намерения или
существующего контракта. Наблюдение в коде, гипотеза и пример — не решение
владельца. Неизвестное запиши в Open Decisions: вопрос, кто решает, зависимое
требование и что блокируется. Несогласованные числа и варианты не становятся нормой.
Для спорного или выведенного при анализе Requirement перед первым Scenario добавь
`**Источник (ненормативно):**` — ссылку на конкретное решение Change Owner в Issue
или пункт согласованной редакции контракта. Ссылка должна оставаться пригодной из
canonical spec после archive; относительной ссылки на активный Proposal недостаточно.
Источник объясняет происхождение, но не заменяет полную норму или approval;
обоснование остаётся в Proposal.
2. **Термины.** Используй названия из затронутых canonical specs и предоставленного
проектного глоссария. Один термин — одно значение в названном контексте. «Счёт»,
«брокерский счёт» и «учётная запись» не взаимозаменяемы. Новый или спорный термин
определи в теле владеющего им Requirement; остальные требования ссылаются на него.
Определение должно различать случаи, а не заменять слово синонимом. Общие термины
передаются в глоссарий через Docs Impact; новый файл словаря на каждый change не нужен.
3. **Атомарность.** Один Requirement — одно независимо принимаемое обязательство.
Если одну часть можно принять, а другую отклонить — раздели. Связанные условия,
сохранность данных при отказе и единый атомарный результат остаются вместе.
Число союзов или SHALL не определяет атомарность.
4. **Явная норма.** Назови субъект, условие применимости и наблюдаемый результат.
Для нового обязательства предпочитай SHALL / SHALL NOT; существующие MUST /
MUST NOT равнозначны и сохраняются. SHOULD / MAY не заменяют неопределённый исход:
допустимая вариативность и исключения должны быть согласованы и описаны.
«Корректно», «быстро», «при необходимости», «и/или», «и т. д.» без определения —
повод уточнить правило. Краткость не оправдывает потерю условий.
5. **Величины и границы.** Для расчёта задай входы, формулу, знак, валюту, точность
и момент округления, если они влияют на результат. Для периода — включительность
границ, дату/время учёта и часовой пояс; для порога — сравнение и точку отсчёта.
Различай ноль, отсутствие значения и неизвестный результат. Не добавляй допуск,
таймаут или округление без источника только ради измеримости.
6. **Свобода реализации.** Описывай «что», а не внутренние классы, библиотеки или
алгоритм. Если внутренний механизм можно заменить без изменения внешнего
обязательства, это design. Внешний формат или протокол допустим в Specs, когда
именно он является согласованным обязательством, а не удобством реализации.
## Requirement and Scenario
Порядок блока: `### Requirement:` с устойчивым именем → общая норма → нужные
определения/таблица → `#### Scenario:`. Для новых требований используй короткое имя
на русском; существующие headings сохраняй для native delta-сопоставления.
Выбирай форму по смыслу (адаптация EARS, не дополнительный синтаксис OpenSpec):
| Смысл | Каркас нормы |
| --- | --- |
| Постоянное свойство | Система SHALL … |
| Реакция на событие | При … система SHALL … |
| Зависимость от состояния | Пока … система SHALL … |
| Ошибка или исключение | Если … система SHALL … |
У ADDED/MODIFIED Requirement минимум один Scenario. GIVEN нужен, когда исходное
состояние влияет на результат; WHEN задаёт событие; THEN — наблюдаемый исход с
определённым ожидаемым значением или составом, не «работает правильно». AND продолжает
предыдущий тип шага: дополняет исходный контекст, событие или ожидаемый исход.
Шаги не описывают внутренние вызовы и селекторы UI.
Сначала общее правило, затем различающие примеры: основной путь, существенная
граница, иной исход, отказ, повтор или конкуренция — по применимости. Каждый сценарий
добавляет новый класс поведения. Не вводи правило только в Scenario и не переписывай
правило целиком для каждой комбинации данных. Сценарии показывают следствия нормы,
но несколько примеров не доказывают универсальный инвариант.
## Representation
| Когда прозы недостаточно | Представление и обязательные уточнения |
| --- | --- |
| Взаимодействуют несколько условий | Таблица решений: область входов, смысл «любое», политика совпадений (одна строка / первая / все), результат отсутствия совпадений или объяснение полноты |
| Результат зависит от истории | Переходы: исходное состояние, событие/условие, новое состояние, видимый эффект; существенные повторы и недопустимые переходы |
| Должно сохраняться свойство | Инвариант/формула с областью действия и единицами; примеры нуля, знака и округления по применимости |
Нормативная таблица находится внутри Requirement до первого Scenario и вводится
фразой с SHALL. Она — единственное определение правила, а не копия соседней прозы.
Неоднозначные пересечения строк — дефект, если явно не задан приоритет или сбор
результатов. Таблица безусловно не нужна каждому требованию. Внутренние состояния
реализации и межсистемные схемы остаются в analysis/design.
## Examples
Учебные примеры формы, не продуктовые решения WealthLedger. В реальном change
периоды, состояния и исходы берутся из его согласованных входов.
### Condition and Boundary
```markdown
## ADDED Requirements
### Requirement: Отбор операций за календарный период
При формировании отчёта система SHALL включать все и только операции выбранного
счёта, дата учёта которых входит в выбранный период включительно по Europe/Moscow.
#### Scenario: Последний день периода и следующий день
- **GIVEN** выбран период 01.10.2026–31.10.2026 и счёт A
- **AND** на счёте A есть операции X с датой учёта 31.10.2026 и Y с датой 01.11.2026
- **WHEN** формируется отчёт
- **THEN** отчёт включает X и не включает Y
```
Плохо: «Система SHALL корректно отбирать операции до конца месяца» — не определены
месяц, границы, дата отбора и счёт. «THEN список корректен» не позволяет проверить исход.
### Decision Table
```markdown
## ADDED Requirements
### Requirement: Различимость неполного и пустого итога
Система SHALL представлять итог расчёта по таблице. «Полнота» означает получение
всех данных выбранной выборки; «есть записи» — наличие хотя бы одной записи.
Оба условия логические. Совпадает ровно одна строка; «любое» означает оба значения.
Покрыты все комбинации.
| Полнота подтверждена | Есть записи | Видимый итог |
| --- | --- | --- |
| Нет | Любое | Недоступен, без числового итога |
| Да | Нет | Ноль и пояснение пустого результата |
| Да | Да | Рассчитанный итог |
#### Scenario: Известная часть не становится окончательной суммой
- **GIVEN** известна одна запись на 100 RUB, но полнота выборки не подтверждена
- **WHEN** пользователь просматривает результат
- **THEN** итог обозначен как недоступный, не показан ни как 100 RUB, ни как ноль
```
Плохо: строки «нет данных → 0» и «данные не полны → недоступно» без определения
«нет данных» — одному входу могут соответствовать два разных результата.
### State Transition
```markdown
## ADDED Requirements
### Requirement: Отмена формирования отчёта
При запросе отмены система SHALL изменять состояние формирования отчёта по таблице.
Область правила — состояния «Ожидает», «Отменён», «Готов»; начальное — «Ожидает».
Совпадает ровно одна строка. Таблица определяет только событие отмены.
| До | После | Результат отмены |
| --- | --- | --- |
| Ожидает | Отменён | Отмена подтверждена, отчёт не будет сформирован |
| Отменён | Отменён | Отмена подтверждена без повторного эффекта |
| Готов | Готов | Отмена отклонена, готовый отчёт сохранён |
#### Scenario: Повтор отмены
- **GIVEN** формирование отчёта уже отменено
- **WHEN** пользователь снова запрашивает отмену
- **THEN** отмена подтверждена, состояние остаётся «Отменён»
```
Плохо: «повтор ничего не делает» — не определён результат для пользователя.
## Review
Используй два прохода на существующем gate Specs (G2 или G3), не новый gate.
Автор выполняет самопроверку; назначенный по режиму reviewer перепроверяет независимо.
| Проход | Что проверить |
| --- | --- |
| Нормоконтроль | Native headings/операции; термины и единицы; явные субъект/условие/исход; атомарность; корректные ссылки; Scenario с проверяемым THEN |
| Смысл и набор | Необходимость и происхождение норм (у спорных/выведенных — источник действительно подтверждает норму, ссылка пригодна после archive); основной путь, альтернативы, отказы и границы; повторы/конкуренция/сохранность по риску; непротиворечивость таблиц и итогового baseline; отсутствие выдуманных решений |
Проверь не только delta, но и получающийся набор вместе с canonical specs:
сохранились ли действующие ограничения, исключения, инварианты и сценарии? MODIFIED
заменяет полный блок; редакторское улучшение не разрешает удалить прежний сценарий
или незаметно переименовать Requirement.
Профиль не отменяет ограничений установленного CLI. При предупреждении о длине
сократи повторения или раздели действительно независимые обязательства; не убирай
условия и не прячь норму в комментарий/код ради успешного `--strict`.
Контрольный вопрос: «Назови существенную ошибочную реализацию и наблюдение, которым
это требование отличит её от соответствующей». Если ответ зависит от догадки,
укажи точную неопределённость. Это эвристика ревью, не доказательство полноты.
Finding: **файл/heading + цитата → нарушенное правило → два возможных толкования
или недостающий исход → вопрос владельцу/адресат исправления**. Reviewer возвращает
находки, не переписывает текст по вкусу. Пример: «до конца месяца» → неясна правая
граница → операция в последний день включается или исключается → уточнить в Specs.
Нерешённый вопрос, меняющий требование или ожидаемый результат, блокирует его gate;
косметическое предпочтение не блокирует. Validation и Findings — в существующем
Gate Log, без нового отчёта на каждый Requirement.
### Trial
Эффект профиля проверяется сравнительным пилотом; до результатов он не подтверждён.
1. До запуска зафиксируй четыре одинаковых для обеих версий задания: простое правило,
ветвление, повтор/состояние и MODIFIED с исходной canonical spec. Для оценки отдельно
запиши согласованные исходы, намеренно оставленные неизвестные и контрольные вопросы.
2. Сравни прежнюю и изменённую инструкции минимум на двух авторах/моделях, каждый
выполняет обе версии. Сохрани входы, prompts, версии инструкций и моделей, доступные
настройки и результаты. Для LLM используй отдельные сессии без ответов другой версии;
для людей чередуй порядок версий, чтобы уменьшить эффект обучения.
3. Независимые читатели отвечают на одинаковые контрольные вопросы по полученным
спецификациям, не зная автора и версии инструкции. Ответы для оценки из шага 1
раскрываются после чтения; согласие читателей само по себе не означает правильность.
4. По каждому заданию сравни расхождения трактовок, ошибки относительно согласованных
исходов, пропущенные случаи, выдуманные нормы и время уточнения/ревью. Сохрани
конкретные примеры ошибок вместе с результатами в Issue пилота.
5. Критерий улучшения согласуй до запуска: меньше смысловых расхождений без роста
ошибок, пропусков и выдуманных норм; допустимое изменение времени определяет владелец.
Если различий нет или данных недостаточно, эффект не подтверждён. Вывод ограничен
проверенными заданиями и авторами/моделями. Совпадение формулировок и успешный CLI
не считаются доказательством одинакового понимания.
## Sources and Adaptation
Из девяти исследований `sdd-spec-quality/*.md` и трёх сводок `result/*.pdf` выбраны
правила с понятной пользой для ручного Markdown-процесса. Первоисточники проверены
30.10.2026; критерии адаптированы, а не перенесены как обязательная сертификация.
| Источник | Что взято и где предел |
| --- | --- |
| [NASA SE Handbook, Appendix C, C.2–C.4](https://www.nasa.gov/reference/appendix-c-how-to-write-a-good-requirement/) | Необходимость, одна мысль, «что, а не как», проверяемость и согласованность; не сертификационный комплект документов |
| [INCOSE GtWR v4 Summary, с. 2–3](https://www.incose.org/wp-content/uploads/legacy/working-groups/requirements-wg/guidetowritingrequirements/incose_rwg_gtwr_v4_summary_sheet.pdf) | C1/C3/C5/C7 для отдельного требования, C10–C14 для набора; R4/R7/R33–R36 — термины, величины, время. Полный платный Guide не заявлен как проверенный |
| [EARS, автор методики](https://alistairmavin.com/ears/) | Каркасы условия/события/состояния/ошибки; русский язык — адаптация, не буквальная английская грамматика |
| [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119.html), [8174 §2](https://www.rfc-editor.org/rfc/rfc8174.html#section-2) | Значения uppercase SHALL/MUST и запретов; наличие ключевого слова само по себе не гарантирует качество |
| [Cucumber, Given/When/Then](https://cucumber.io/docs/gherkin/reference/) | Исходное состояние, событие, наблюдаемый исход; Markdown Scenario не становится исполняемым Gherkin-тестом |
Из предложений не приняты: жёсткие лимиты слов/сценариев, подсчёт SHALL вместо
атомарности, обязательные REQ-ID и скрытые атрибуты, JSON-first, новые линтеры и gates.
Из нормоконтроля конструкторской документации заимствовано разделение проверки формы
и смысла; соответствие ГОСТ, DO-178C или ISO/IEC/IEEE 29148 не заявляется. Таблицы и
инварианты используются по риску; обязательная формальная модель каждому change не нужна.