devcontour-harness 0.1.0-alpha.13 → 0.1.0-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,7 @@ Headless-движок исполнения инженерных поручени
5
5
  интеграция с принятой веткой через compare-and-swap и машинный результат с SHA
6
6
  и доказательствами.
7
7
 
8
- > Статус: `0.1.0-alpha.13` — предварительный выпуск (alpha). Договоры
8
+ > Статус: `0.1.0-alpha.16` — предварительный выпуск (alpha). Договоры
9
9
  > `v1alpha1` могут измениться между alpha-версиями; закрепляйте точную версию.
10
10
  > Файл → ревью плана → кандидат → интеграция → принятие → результат JSON, с
11
11
  > ограниченным восстановлением, повторным использованием кандидата, бюджетами,
@@ -28,7 +28,7 @@ Headless-движок исполнения инженерных поручени
28
28
  Из npm — точная версия (воспроизводимо) или последняя alpha по тегу:
29
29
 
30
30
  ```sh
31
- npm install --save-exact devcontour-harness@0.1.0-alpha.13 # точная версия
31
+ npm install --save-exact devcontour-harness@0.1.0-alpha.16 # точная версия
32
32
  # или: npm install --save-exact devcontour-harness@alpha # текущая alpha
33
33
  npx harness --version
34
34
  ```
@@ -123,6 +123,36 @@ PASS» нет. Адаптеры хоста реализуют порты `Execut
123
123
  `devcontour-harness/schemas/<имя>.schema.json`. Декларации используют типы
124
124
  Node.js: TypeScript-потребителю нужен `@types/node` (или `skipLibCheck`).
125
125
 
126
+ ## Выпуск 0.1.0-alpha.16
127
+
128
+ Отказ по файлу эталонного набора — только по строковому литералу, без ложных
129
+ отказов на комментариях и похожих именах; reviewer контракта видит минимумы
130
+ семейств. Подробно — [заметки выпуска](docs/release-notes/0.1.0-alpha.16.md);
131
+ alpha.14 и alpha.15 — локальные выпуски, в npm не публиковались.
132
+
133
+ ## Выпуск 0.1.0-alpha.15
134
+
135
+ Эталонные наборы защищены от подгонки. Подробно —
136
+ [заметки выпуска](docs/release-notes/0.1.0-alpha.15.md); alpha.14 — локальный
137
+ выпуск, в npm не публиковался.
138
+
139
+ - Writer и reviewer кода знают файлы эталонных наборов; кандидат, чей
140
+ изменённый файл называет файл набора, отклоняется до gates.
141
+ - `crossChecks[].artifacts`: закреплённый скрипт или журнал сверки эталона.
142
+ - Обязательство, которое поручение выбрать не может, отклоняется сразу; ID
143
+ testcase node:test (`test.<имя>`) описан и подсказан в отказе.
144
+
145
+ ## Выпуск 0.1.0-alpha.14
146
+
147
+ Проверка по закреплённым эталонным наборам. Подробно —
148
+ [заметки выпуска](docs/release-notes/0.1.0-alpha.14.md).
149
+
150
+ - `verification: "reference"` в договоре проверки: обещание проверяется
151
+ наборами ответов независимого эталона, закреплёнными артефактами контракта;
152
+ gate без генератора подтверждает отчётом свою долю входов и семейств.
153
+ - `obligations[].gates`: обязательство исполняют несколько gates.
154
+ - Reviewer контракта видит пределы наборов (`gaps`) и сверку эталона.
155
+
126
156
  ## Выпуск 0.1.0-alpha.13
127
157
 
128
158
  Controller mode для задач Relay и установка без лишних вопросов. Подробно —
@@ -267,6 +267,12 @@ runtime-граф пакета.
267
267
  и файлы, не совпадающие с целевой веткой, отклоняются до вызова reviewer.
268
268
  Поручение включает механизм полем `properties`; свойства, которых нет в его
269
269
  договорах или которые исполняет не генеративный gate, не согласуются.
270
+ Обязательство может назвать несколько gates (`gates`) и способ
271
+ `reference`: сверку с закреплёнными эталонными наборами вместо генератора.
272
+ Gate эталонных наборов получает путь отчёта свойств и без `property` и
273
+ обязан подтвердить свою долю входов и семейств; пределы наборов (`gaps`)
274
+ reviewer контракта видит отдельно
275
+ ([договор](contracts.md#способы-исполнения-обязательства-property-и-reference)).
270
276
  Генеративный gate получает seed controller (`DEVCONTOUR_SEED`, свой у
271
277
  попытки, фазы и gate), селектор свойств и закреплённый корпус; отчёт
272
278
  свойств читается при любом исходе из каталога вне worktree. Gate проходит,
package/docs/contracts.md CHANGED
@@ -182,6 +182,106 @@ Git blob в репозитории `repositoryId`); `checks` — договор
182
182
  корпуса. Прошедший ревью документ хранится по digest (`contract-documents`):
183
183
  из него движок строит манифест генеративного gate поручения.
184
184
 
185
+ #### Способы исполнения обязательства: `property` и `reference`
186
+
187
+ Обязательство исполняют его gates: `obligations[].gates` (1–10 ID) или, без
188
+ поля, `checks.gate`. Способ — `verification`:
189
+
190
+ - `property` (поле не указано) — генеративная проверка, как прежде: каждый gate
191
+ обязательства генеративный (`gate.property`), отчёт свойств каждого
192
+ подтверждает полное покрытие обязательства (`coverage.minCases` и
193
+ семейства), корпус пополняет только gate договора;
194
+ - `reference` — сверка с закреплёнными эталонными наборами. Ответы
195
+ независимого эталона (точный решатель, полный перебор, таблица DP)
196
+ получены заранее, сверены с другим способом и закреплены артефактами
197
+ контракта; gate сверяет с ними реализацию. Генератор не нужен, поэтому gate
198
+ может быть обычным test-gate без `property`.
199
+
200
+ `reference` описывает:
201
+
202
+ | Поле | Смысл |
203
+ | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
204
+ | `oracle.description`, `oracle.limits` | эталон, его версия и пределы (время решения, что исключено из наборов) |
205
+ | `crossChecks[]` `{family, against, matches, total, artifacts?}` | сверка эталона с другим способом на семействе входов; `matches < total` — отказ; `artifacts` — закреплённый скрипт или журнал, воспроизводящий сверку |
206
+ | `sets[]` `{gate, artifacts, minCases, families}` | набор: gate, файлы набора (артефакты контракта), доля входов и семейств этого gate |
207
+ | `gaps` | чего наборы не доказывают: обобщение за пределы входов, классы вне наборов |
208
+
209
+ Структурные правила (`declarationProblems`, до вызова модели): у каждого gate
210
+ обязательства есть набор, gate набора — среди gates обязательства, файлы
211
+ наборов — артефакты контракта, сумма `sets[].minCases` не меньше
212
+ `coverage.minCases`, сумма долей каждого семейства покрытия не меньше его
213
+ `minCases`, семейства набора объявлены в покрытии и не превышают минимум
214
+ набора, сверка эталона без расхождений, файлы сверки (`crossChecks[].artifacts`)
215
+ — артефакты контракта; корпус у эталонного обязательства не включается.
216
+ Требование генеративного gate к `reference` не применяется; остальные
217
+ правила (`method`, бюджеты, spike) те же. Обязательство `property` любого
218
+ обещания (и `invariant`, и `functional`) на gate без `property` отклоняется:
219
+ поручение такое свойство выбрать не может (`orderPropertyProblems`), и
220
+ договор был бы мёртвым.
221
+
222
+ Доказательство — тот же отчёт свойств. Для gate, которому манифест поручения
223
+ назначает эталонное свойство, controller задаёт путь отчёта
224
+ (`DEVCONTOUR_PROPERTY_REPORT`) и селектор (`DEVCONTOUR_PROPERTIES`) и без
225
+ `gate.property`. Запись манифеста эталонного свойства — доля этого gate:
226
+ сумма `minCases` и семейств его наборов и `reference.artifacts` (файлы
227
+ наборов); поле есть только у эталонных свойств, так что digest прежних
228
+ манифестов не меняется. Gate проходит, только если отчёт называет свойство
229
+ со статусом `passed`, числом проверенных входов и семейств не меньше доли и
230
+ testcase с тем же ID в JUnit; зелёный JUnit и код 0 без отчёта — отказ
231
+ («Проверка по эталонным наборам не отчиталась»). Приёмка требует решающую
232
+ запись обеих фаз с манифестом от каждого gate обязательства. Файлы наборов —
233
+ артефакты контракта, поэтому попытка не может их изменить (защищённые пути).
234
+
235
+ Reviewer контракта получает эталонные обязательства отдельно (`referenceNote`):
236
+ эталон, сверку, наборы и `gaps`. Обещание, которое опирается только на
237
+ `gaps`, без другого способа (генеративного свойства, инварианта,
238
+ аналитического основания), — блокирующая находка. Сверка без `artifacts` —
239
+ непроверенное утверждение автора, и reviewer оценивает её так.
240
+
241
+ Ответы наборов лежат в рабочем дереве, поэтому реализация могла бы читать их
242
+ или повторять их ответы и проходить каждый набор. Защита в два слоя:
243
+ writer и reviewer кода получают список файлов наборов (`referenceSetFiles`,
244
+ `referenceCodeNote`), и для reviewer чтение файлов наборов из кода
245
+ реализации, вшитые ответы или особые случаи для входов наборов — блокирующая
246
+ находка; controller отклоняет кандидата (`scope-violation`, до gates), если
247
+ изменённый файл называет файл набора внутри строкового литерала (`'…'`,
248
+ `"…"`, `` `…` ``): имя файла набора целым токеном — по краям нет буквы,
249
+ цифры, `_`, `-` или `.`, так что путь и `../имя` совпадают, а `data.json` с
250
+ набором `a.json` или `testcases.json` с `cases.json` — нет (`setFileReference`).
251
+ Комментарии `//` и `/* */` и файлы без кода (`.md`, `.txt`, `.rst`, `.adoc`,
252
+ каталог `docs/`) не проверяются. Тесты исполнителя, которые не артефакты
253
+ контракта, проверяются тем же правилом: через них ответы тоже можно подать
254
+ реализации. Остаточный риск: имя, собранное во время исполнения
255
+ (`` `${name}-golden.json` ``), копия ответов без имени файла и обобщение,
256
+ подогнанное под входы, механически не ловятся — их ловит ревью кода; строка
257
+ кода, которая законно называет набор (не артефакт контракта), отклоняется.
258
+
259
+ Пределы проверки долей: controller сверяет, что доли наборов покрывают
260
+ общий минимум и минимумы семейств и что gate отчитался своей долей, но не
261
+ сравнивает доли с размером файлов набора (сколько входов в нём на самом деле)
262
+ и не проверяет, что входы различны. Reviewer контракта видит минимумы
263
+ обязательства и семейств рядом с наборами (`referenceNote`) и оценивает это
264
+ сам.
265
+
266
+ #### ID testcase и отчёта
267
+
268
+ Свойство, `testId` отчёта и testcase JUnit — один ID. ID testcase — это
269
+ `classname.name` (без `classname` — `name`). Генератор отчёта задаёт
270
+ `classname` по-своему: node:test (`--test-reporter=junit`) всегда пишет
271
+ `classname="test"`, и тест `test('knapsack-optimal', …)` получает ID
272
+ `test.knapsack-optimal` — таким должен быть и property ID; JUnit-отчёт
273
+ собственного checker (как `harness.mjs` в примерах) пишет только `name`, и ID
274
+ совпадает с именем. Если testcase с ID свойства нет, а есть
275
+ `<classname>.<ID>`, отказ называет найденный ID.
276
+
277
+ Совместимость: поля `gates`, `verification`, `reference` необязательны, договор
278
+ без них разбирается, проверяется и даёт тот же манифест, digest и основание
279
+ корпуса (`suiteBasis` включает новые поля, только когда они объявлены;
280
+ `gates`, равные gate договора, — то же основание, что без поля, а digest
281
+ документа контракта при этом другой).
282
+ Версия договора остаётся `version: 1`; прежние версии harness договор с
283
+ новыми полями отклоняют строгой схемой.
284
+
185
285
  ## Модель исполнения
186
286
 
187
287
  Схемы в `execution.ts` — то, что `ExecutionStore` хранит транзакционно:
@@ -13,7 +13,7 @@
13
13
  ```sh
14
14
  mkdir harness-demo && cd harness-demo
15
15
  npm init -y >/dev/null
16
- npm install --save-exact devcontour-harness@0.1.0-alpha.13
16
+ npm install --save-exact devcontour-harness@0.1.0-alpha.16
17
17
  npx harness --version
18
18
  npx harness doctor
19
19
  ```
@@ -0,0 +1,69 @@
1
+ # devcontour-harness 0.1.0-alpha.14
2
+
3
+ > Локальный выпуск: в npm не публиковался. Его изменения вошли в
4
+ > [0.1.0-alpha.15](0.1.0-alpha.15.md).
5
+
6
+ Проверка по закреплённым эталонным наборам в договоре проверки и несколько
7
+ gates у одного обязательства. Gates, `maxAttempts`, бюджеты попыток и
8
+ повторов, правила находок, изоляция, принятие target ref и генеративная
9
+ проверка (`property`) не менялись.
10
+
11
+ ## Что нового
12
+
13
+ - **`verification: "reference"`.** Вычислительное обещание (оптимальность,
14
+ полнота, точность, производительность) можно проверить не генератором, а
15
+ наборами ответов независимого эталона, посчитанными заранее и закреплёнными
16
+ артефактами контракта. Обязательство описывает эталон и его пределы
17
+ (`oracle`), сверку эталона с другим способом (`crossChecks`: семейство,
18
+ способ, совпало из всего), наборы (`sets`: gate, файлы, доля входов и
19
+ семейств) и то, чего наборы не доказывают (`gaps`). Gate такого
20
+ обязательства — обычный test-gate без `property`
21
+ ([договор](../contracts.md#способы-исполнения-обязательства-property-и-reference)).
22
+ - **`obligations[].gates`.** Обязательство называет свои gates (1–10); без
23
+ поля его исполняет `checks.gate`, как раньше. Генеративное обязательство
24
+ проверяет полное покрытие на каждом своём gate; эталонное — долю наборов
25
+ каждого gate.
26
+ - **Доказательство доли.** Gate, которому манифест поручения назначает
27
+ эталонное свойство, получает путь отчёта свойств и селектор и без
28
+ `gate.property`. Отчёт обязан назвать свойство со статусом `passed` и
29
+ числом проверенных входов и семейств не меньше доли этого gate, JUnit —
30
+ testcase с тем же ID; зелёный JUnit и код 0 без отчёта — отказ gate.
31
+ Приёмка требует запись с манифестом от каждого gate обязательства.
32
+ - **Структурные отказы до вызова модели:** gate обязательства без набора,
33
+ набор чужого gate, файл набора не среди артефактов контракта, доли наборов
34
+ меньше общего минимума или минимума семейства, семейство набора не из
35
+ покрытия, сверка эталона с расхождениями, корпус у эталонного
36
+ обязательства, корпус генеративного обязательства не на gate договора.
37
+ - **Reviewer контракта** получает эталонные обязательства отдельно: эталон,
38
+ сверку, наборы и `gaps` (`referenceNote`). Обещание, которое опирается
39
+ только на `gaps`, — блокирующая находка.
40
+ - Самопроверка исполнителя запускает и gates эталонных наборов.
41
+
42
+ ## Изменения договора
43
+
44
+ Добавления в `checkDeclarationSchema`: `obligations[].gates`,
45
+ `obligations[].verification` (`property` | `reference`) и
46
+ `obligations[].reference`; в `CheckManifest.properties[]` — `reference`
47
+ (только у эталонных свойств). Новые экспорты: `obligationGates`,
48
+ `isReference`, `referenceNote`, `expectsReference`, `referenceSchema`. Без
49
+ новых полей разбор, отказы, манифест, его digest и основание корпуса
50
+ (`suiteBasis`) те же, что в alpha.13. Сообщение «… не генеративный (нет
51
+ property)» теперь называется для каждого gate генеративного обязательства.
52
+
53
+ ## Совместимость
54
+
55
+ Формат состояния тот же. Договор с новыми полями alpha.13 и раньше не
56
+ принимают (строгая схема): состояние с таким контрактом откатывается только
57
+ через копию. Обновление и откат — по [upgrade](../upgrade.md).
58
+
59
+ ## Проверка выпуска
60
+
61
+ `npm run check` (lint, typecheck, schemas, build, весь набор тестов, package
62
+ smoke из установленного архива) на macOS arm64, Node.js 24.3.
63
+ `tests/reference.test.ts`: структурные отказы и принятый договор на gates без
64
+ генератора, манифест доли gate, прежние манифест и основание корпуса
65
+ договора без новых полей, согласование поручения, подсказка reviewer,
66
+ самопроверка; на fixture runtime — два gate эталонных наборов доводят
67
+ поручение до приёмки, недобор входов при зелёном JUnit и коде 0, отсутствие
68
+ отчёта и расхождение с эталоном — отказ gate. Каждая новая проверка падает на
69
+ своём мутанте реализации. Живые модели не вызывались.
@@ -0,0 +1,62 @@
1
+ # devcontour-harness 0.1.0-alpha.15
2
+
3
+ > Локальный выпуск: в npm не публиковался. Его изменения вошли в
4
+ > [0.1.0-alpha.16](0.1.0-alpha.16.md).
5
+
6
+ Защита эталонной проверки от подгонки под наборы, закреплённые файлы сверки
7
+ эталона и ID testcase node:test. Включает всё из
8
+ [0.1.0-alpha.14](0.1.0-alpha.14.md): alpha.14 — локальный выпуск, в npm не
9
+ публиковался; первая публикуемая версия с эталонными наборами — alpha.15.
10
+ Gates, `maxAttempts`, бюджеты попыток и повторов, правила находок, изоляция,
11
+ принятие target ref и формат состояния не менялись.
12
+
13
+ ## Что нового
14
+
15
+ - **Ответы наборов не подсказка реализации.** Writer и reviewer кода получают
16
+ список файлов эталонных наборов поручения. Для reviewer чтение их из кода
17
+ реализации, вшитые ответы и особые случаи для входов наборов — блокирующая
18
+ находка. Controller отклоняет кандидата до gates (`scope-violation`
19
+ «Реализация ссылается на файлы эталонных наборов»), если изменённый файл
20
+ содержит путь или имя файла набора. Имя, собранное во время исполнения, и
21
+ копия ответов без имени файла механически не ловятся — их ловит ревью кода
22
+ ([договор](../contracts.md#способы-исполнения-обязательства-property-и-reference)).
23
+ - **`crossChecks[].artifacts`.** Сверка эталона может ссылаться на
24
+ закреплённый скрипт или журнал, который её воспроизводит; файлы обязаны
25
+ быть артефактами контракта. Reviewer контракта оценивает сверку без них
26
+ как непроверенное утверждение автора.
27
+ - **Мёртвые обязательства.** Обязательство `property` любого обещания на
28
+ gate без `property` отклоняется до вызова модели: поручение его выбрать не
29
+ может. Прежде так отклонялись только вычислительные обещания.
30
+ - **ID testcase.** Отказ «testcase X отсутствует в JUnit» называет найденный
31
+ `<classname>.X` (node:test пишет `classname="test"`, и ID свойства для него
32
+ — `test.<имя теста>`); правило описано в
33
+ [договоре](../contracts.md#id-testcase-и-отчёта).
34
+ - Сообщение отказа gate, где генеративные и эталонные свойства вместе:
35
+ «Проверка свойств и эталонных наборов …».
36
+ - `gates` обязательства, равные `checks.gate`, дают то же основание корпуса,
37
+ что и без поля.
38
+
39
+ ## Изменения договора
40
+
41
+ Добавления: `reference.crossChecks[].artifacts` (1–10 путей), экспорты
42
+ `referenceSetFiles` и `referenceCodeNote`. Изменение отказа: обязательство
43
+ `property` с необязательным обещанием (`functional`, `invariant`, `other`) на
44
+ gate без `property` теперь — структурный отказ договора (текст «… не
45
+ генеративный (нет property) — поручение не сможет выбрать это свойство; …»;
46
+ у вычислительных обещаний текст тоже дополнен). Договор без новых полей даёт
47
+ тот же манифест, digest и основание корпуса.
48
+
49
+ ## Совместимость
50
+
51
+ Формат состояния тот же. Договор с новыми полями alpha.13 и раньше не
52
+ принимают (строгая схема). Обновление и откат — по [upgrade](../upgrade.md).
53
+
54
+ ## Проверка выпуска
55
+
56
+ `npm run check` на macOS arm64, Node.js 24.3. `tests/reference.test.ts`
57
+ (14 тестов): к проверкам alpha.14 добавлены отказ кандидата, читающего файл
58
+ набора, список наборов в запросах writer и reviewer, testcase с другим ID,
59
+ настоящий JUnit node:test (`test.<имя>`), файлы сверки, мёртвое
60
+ обязательство-инвариант, основание корпуса при `gates` равных gate договора.
61
+ Каждая новая проверка падает на своём мутанте (29 из 29). Живые модели не
62
+ вызывались.
@@ -0,0 +1,36 @@
1
+ # devcontour-harness 0.1.0-alpha.16
2
+
3
+ Проверка файлов эталонных наборов без ложных отказов. Включает всё из
4
+ [0.1.0-alpha.15](0.1.0-alpha.15.md) и [0.1.0-alpha.14](0.1.0-alpha.14.md):
5
+ обе — локальные выпуски, в npm не публиковались; первая публикуемая версия с
6
+ эталонными наборами — alpha.16. Gates, `maxAttempts`, бюджеты попыток и
7
+ повторов, правила находок, изоляция, принятие target ref и формат состояния
8
+ не менялись.
9
+
10
+ ## Что нового
11
+
12
+ - **Отказ по файлу набора — только по строковому литералу.** В alpha.15
13
+ кандидат отклонялся, если изменённый файл где угодно содержал путь или имя
14
+ файла набора: комментарий, свой тест исполнителя, `data.json` при наборе
15
+ `a.json`. Теперь имя файла набора должно стоять целым токеном внутри
16
+ строкового литерала (`'…'`, `"…"`, `` `…` ``); комментарии `//` и `/* */` и
17
+ файлы без кода (`.md`, `.txt`, `.rst`, `.adoc`, `docs/`) не проверяются.
18
+ Тесты исполнителя проверяются тем же правилом. Ложный отказ тратил попытку.
19
+ - **Reviewer контракта видит минимумы.** `referenceNote` показывает общий
20
+ минимум обязательства, минимумы семейств и доли семейств каждого набора.
21
+ Сравнения долей с фактическим размером файлов набора нет — это описано в
22
+ [договоре](../contracts.md#способы-исполнения-обязательства-property-и-reference).
23
+ - Новый экспорт `setFileReference(path, text, sets)`.
24
+
25
+ ## Совместимость
26
+
27
+ Формат состояния и договор те же, что в alpha.15. Обновление и откат — по
28
+ [upgrade](../upgrade.md).
29
+
30
+ ## Проверка выпуска
31
+
32
+ `npm run check` на macOS arm64, Node.js 24.3. `tests/reference.test.ts`
33
+ (15 тестов): комментарий, текст, свой тест без литерала, похожие имена и
34
+ непарная кавычка — без отказа; литеральный путь, `'golden-a.json'`, путь в
35
+ шаблоне, `../имя` и импорт из теста исполнителя — отказ. 36 из 36 мутантов
36
+ реализации обнаружены. Живые модели не вызывались.
package/docs/upgrade.md CHANGED
@@ -21,20 +21,21 @@
21
21
 
22
22
  ## Матрица форматов
23
23
 
24
- | Состояние, записанное… | Читает 0.1.0-alpha.1 | Читает 0.1.0-alpha.2 | Читает 0.1.0-alpha.6 | Читает 0.1.0-alpha.7 | Читает 0.1.0-alpha.8 | Читает 0.1.0-alpha.9 | Читает 0.1.0-alpha.10 | Читает 0.1.0-alpha.11 | Читает 0.1.0-alpha.12 | Читает 0.1.0-alpha.13 | Пишет поверх | Примечание |
25
- | ------------------------------------------------------------------------------ | ------------------------ | ------------------------ | ----------------------- | -------------------- | -------------------- | -------------------- | --------------------- | --------------------- | --------------------- | --------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
26
- | standalone `stateVersion: 1` версией alpha.1 | да | да | да | да | да | да | да | да | да | да | да | одна база SQLite: документ, события, локальные записи |
27
- | хост, центральная база | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да | данные не переносятся; новые поля необязательны |
28
- | хост, базы компонентов | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да | нужна копия всех баз при остановленных writers |
29
- | alpha.2 после штатной остановки controller | да | да | да | да | да | да | да | да | да | да | да | роль controller снята — нового поля в состоянии нет |
30
- | alpha.2 с живой или брошенной ролью controller | **нет**, отказ до записи | да | да | да | да | да | да | да | да | да | — | роль хранит `engineVersion`; строгая схема alpha.1 его не знает → откат через копию |
31
- | alpha.4 с совместной проверкой | **нет**, отказ до записи | **нет**, отказ до записи | да | да | да | да | да | да | да | да | — | проверка хранит `engineVersion`; прежние версии его не знают → откат через копию |
32
- | alpha.6 standalone с записями ревью нового протокола или доставкой `uncertain` | **нет**, отказ до записи | **нет**, отказ до записи | да | да | да | да | да | да | да | да | — | `reviewRound`, `findings[].id/status`, статус доставки `uncertain`; alpha.4/alpha.5 отказывают `STATE_VERSION_UNSUPPORTED` до записи → откат через копию |
33
- | alpha.6, хост DevContour (адаптер alpha.4) | — | — | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да | адаптер DevContour alpha.4 открывает такое состояние без отказа и пишет роль controller и события; новые поля сохраняются → для отката всё равно копия |
34
- | alpha.7 с новым `inspection` ревью кода | не проверялось | не проверялось | **нет** (строгая схема) | да | да | да | да | да | да | да | — | новые значения `source`, `exitCode: null`, `origins`/`context`/`excluded`; строгая схема alpha.6 их не принимает, поведение прежних версий при открытии не проверялось → откат через копию |
35
- | неизвестная `stateVersion` | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет | `STATE_VERSION_UNSUPPORTED`, exit 4 |
36
-
37
- Столбец alpha.2 относится и к alpha.3; alpha.4 и alpha.5 читают все строки, кроме неизвестной `stateVersion` и строк alpha.6 с новыми полями (standalone — отказ до записи) и строки alpha.7. alpha.8, alpha.9, alpha.10, alpha.11, alpha.12 и alpha.13 формат состояния не меняют и читают всё, что читает alpha.7. Каждая следующая версия добавляет сюда свой столбец. Отказ неизвестного
24
+ | Состояние, записанное… | Читает 0.1.0-alpha.1 | Читает 0.1.0-alpha.2 | Читает 0.1.0-alpha.6 | Читает 0.1.0-alpha.7 | Читает 0.1.0-alpha.8 | Читает 0.1.0-alpha.9 | Читает 0.1.0-alpha.10 | Читает 0.1.0-alpha.11 | Читает 0.1.0-alpha.12 | Читает 0.1.0-alpha.13 | Читает 0.1.0-alpha.14 | Читает 0.1.0-alpha.15 | Читает 0.1.0-alpha.16 | Пишет поверх | Примечание |
25
+ | ------------------------------------------------------------------------------ | ------------------------ | ------------------------ | ----------------------- | ----------------------- | ----------------------- | ----------------------- | ----------------------- | ----------------------- | ----------------------- | ----------------------- | --------------------- | --------------------- | --------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
26
+ | standalone `stateVersion: 1` версией alpha.1 | да | да | да | да | да | да | да | да | да | да | да | да | да | да | одна база SQLite: документ, события, локальные записи |
27
+ | хост, центральная база | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да | данные не переносятся; новые поля необязательны |
28
+ | хост, базы компонентов | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да | нужна копия всех баз при остановленных writers |
29
+ | alpha.2 после штатной остановки controller | да | да | да | да | да | да | да | да | да | да | да | да | да | да | роль controller снята — нового поля в состоянии нет |
30
+ | alpha.2 с живой или брошенной ролью controller | **нет**, отказ до записи | да | да | да | да | да | да | да | да | да | да | да | да | — | роль хранит `engineVersion`; строгая схема alpha.1 его не знает → откат через копию |
31
+ | alpha.4 с совместной проверкой | **нет**, отказ до записи | **нет**, отказ до записи | да | да | да | да | да | да | да | да | да | да | да | — | проверка хранит `engineVersion`; прежние версии его не знают → откат через копию |
32
+ | alpha.6 standalone с записями ревью нового протокола или доставкой `uncertain` | **нет**, отказ до записи | **нет**, отказ до записи | да | да | да | да | да | да | да | да | да | да | да | — | `reviewRound`, `findings[].id/status`, статус доставки `uncertain`; alpha.4/alpha.5 отказывают `STATE_VERSION_UNSUPPORTED` до записи → откат через копию |
33
+ | alpha.6, хост DevContour (адаптер alpha.4) | — | — | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер) | да | адаптер DevContour alpha.4 открывает такое состояние без отказа и пишет роль controller и события; новые поля сохраняются → для отката всё равно копия |
34
+ | alpha.7 с новым `inspection` ревью кода | не проверялось | не проверялось | **нет** (строгая схема) | да | да | да | да | да | да | да | да | да | да | — | новые значения `source`, `exitCode: null`, `origins`/`context`/`excluded`; строгая схема alpha.6 их не принимает, поведение прежних версий при открытии не проверялось → откат через копию |
35
+ | alpha.14 с договором проверки `reference` или `gates` обязательства | не проверялось | не проверялось | не проверялось | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | да | да | да | — | контракт хранится строгой схемой (`contract-documents`): прежние версии новых полей `gates`, `verification`, `reference` не знают → откат через копию |
36
+ | неизвестная `stateVersion` | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет | `STATE_VERSION_UNSUPPORTED`, exit 4 |
37
+
38
+ Столбец alpha.2 относится и к alpha.3; alpha.4 и alpha.5 читают все строки, кроме неизвестной `stateVersion` и строк alpha.6 с новыми полями (standalone — отказ до записи) и строки alpha.7. alpha.8, alpha.9, alpha.10, alpha.11, alpha.12 и alpha.13 формат состояния не меняют и читают всё, что читает alpha.7; alpha.14 и alpha.15 (локальные, не опубликованы) и alpha.16 читают всё, что читает alpha.13, и добавляют необязательные поля договора проверки (строка alpha.14). Каждая следующая версия добавляет сюда свой столбец. Отказ неизвестного
38
39
  формата до записи проверяют тесты совместимости пакета
39
40
  <!-- repo-only -->(`tests/compatibility.test.ts`)<!-- /repo-only -->.
40
41
 
@@ -2,6 +2,41 @@ import { z } from 'zod';
2
2
  export declare const promiseKinds: readonly ["functional", "accuracy", "optimality", "completeness", "performance", "invariant", "other"];
3
3
  /** Вычислительные обещания: без независимого способа проверки их не утверждают. */
4
4
  export declare const strongPromises: ReadonlySet<string>;
5
+ /**
6
+ * Проверка по закреплённым эталонным наборам (`verification: 'reference'`).
7
+ *
8
+ * Ответы независимого эталона (решатель, полный перебор, таблица DP)
9
+ * получены заранее, сверены с другим способом на семействах входов и
10
+ * закреплены артефактами контракта. Gate сверяет реализацию с наборами и
11
+ * отчитывается тем же отчётом свойств: число проверенных входов по свойству
12
+ * и по семействам. Каждый набор принадлежит одному gate: его минимум и
13
+ * минимумы семейств — доля этого gate в покрытии обязательства. Обобщения за
14
+ * пределы наборов такой способ не доказывает — это называет `gaps`.
15
+ */
16
+ export declare const referenceSchema: z.ZodObject<{
17
+ oracle: z.ZodObject<{
18
+ description: z.ZodString;
19
+ limits: z.ZodString;
20
+ }, z.core.$strict>;
21
+ crossChecks: z.ZodArray<z.ZodObject<{
22
+ family: z.ZodString;
23
+ against: z.ZodString;
24
+ matches: z.ZodNumber;
25
+ total: z.ZodNumber;
26
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodString>>;
27
+ }, z.core.$strict>>;
28
+ sets: z.ZodArray<z.ZodObject<{
29
+ gate: z.ZodString;
30
+ artifacts: z.ZodArray<z.ZodString>;
31
+ minCases: z.ZodNumber;
32
+ families: z.ZodDefault<z.ZodArray<z.ZodObject<{
33
+ id: z.ZodString;
34
+ minCases: z.ZodNumber;
35
+ }, z.core.$strict>>>;
36
+ }, z.core.$strict>>;
37
+ gaps: z.ZodString;
38
+ }, z.core.$strict>;
39
+ export type ReferenceVerification = z.infer<typeof referenceSchema>;
5
40
  export declare const obligationSchema: z.ZodObject<{
6
41
  property: z.ZodString;
7
42
  requirements: z.ZodArray<z.ZodString>;
@@ -63,6 +98,34 @@ export declare const obligationSchema: z.ZodObject<{
63
98
  environment: z.ZodString;
64
99
  }, z.core.$strict>>;
65
100
  }, z.core.$strict>;
101
+ gates: z.ZodOptional<z.ZodArray<z.ZodString>>;
102
+ verification: z.ZodOptional<z.ZodEnum<{
103
+ property: "property";
104
+ reference: "reference";
105
+ }>>;
106
+ reference: z.ZodOptional<z.ZodObject<{
107
+ oracle: z.ZodObject<{
108
+ description: z.ZodString;
109
+ limits: z.ZodString;
110
+ }, z.core.$strict>;
111
+ crossChecks: z.ZodArray<z.ZodObject<{
112
+ family: z.ZodString;
113
+ against: z.ZodString;
114
+ matches: z.ZodNumber;
115
+ total: z.ZodNumber;
116
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodString>>;
117
+ }, z.core.$strict>>;
118
+ sets: z.ZodArray<z.ZodObject<{
119
+ gate: z.ZodString;
120
+ artifacts: z.ZodArray<z.ZodString>;
121
+ minCases: z.ZodNumber;
122
+ families: z.ZodDefault<z.ZodArray<z.ZodObject<{
123
+ id: z.ZodString;
124
+ minCases: z.ZodNumber;
125
+ }, z.core.$strict>>>;
126
+ }, z.core.$strict>>;
127
+ gaps: z.ZodString;
128
+ }, z.core.$strict>>;
66
129
  hard: z.ZodDefault<z.ZodBoolean>;
67
130
  feasibility: z.ZodOptional<z.ZodObject<{
68
131
  spike: z.ZodString;
@@ -134,6 +197,34 @@ export declare const checkDeclarationSchema: z.ZodObject<{
134
197
  environment: z.ZodString;
135
198
  }, z.core.$strict>>;
136
199
  }, z.core.$strict>;
200
+ gates: z.ZodOptional<z.ZodArray<z.ZodString>>;
201
+ verification: z.ZodOptional<z.ZodEnum<{
202
+ property: "property";
203
+ reference: "reference";
204
+ }>>;
205
+ reference: z.ZodOptional<z.ZodObject<{
206
+ oracle: z.ZodObject<{
207
+ description: z.ZodString;
208
+ limits: z.ZodString;
209
+ }, z.core.$strict>;
210
+ crossChecks: z.ZodArray<z.ZodObject<{
211
+ family: z.ZodString;
212
+ against: z.ZodString;
213
+ matches: z.ZodNumber;
214
+ total: z.ZodNumber;
215
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodString>>;
216
+ }, z.core.$strict>>;
217
+ sets: z.ZodArray<z.ZodObject<{
218
+ gate: z.ZodString;
219
+ artifacts: z.ZodArray<z.ZodString>;
220
+ minCases: z.ZodNumber;
221
+ families: z.ZodDefault<z.ZodArray<z.ZodObject<{
222
+ id: z.ZodString;
223
+ minCases: z.ZodNumber;
224
+ }, z.core.$strict>>>;
225
+ }, z.core.$strict>>;
226
+ gaps: z.ZodString;
227
+ }, z.core.$strict>>;
137
228
  hard: z.ZodDefault<z.ZodBoolean>;
138
229
  feasibility: z.ZodOptional<z.ZodObject<{
139
230
  spike: z.ZodString;
@@ -233,6 +324,34 @@ export declare const contractDocumentSchema: z.ZodObject<{
233
324
  environment: z.ZodString;
234
325
  }, z.core.$strict>>;
235
326
  }, z.core.$strict>;
327
+ gates: z.ZodOptional<z.ZodArray<z.ZodString>>;
328
+ verification: z.ZodOptional<z.ZodEnum<{
329
+ property: "property";
330
+ reference: "reference";
331
+ }>>;
332
+ reference: z.ZodOptional<z.ZodObject<{
333
+ oracle: z.ZodObject<{
334
+ description: z.ZodString;
335
+ limits: z.ZodString;
336
+ }, z.core.$strict>;
337
+ crossChecks: z.ZodArray<z.ZodObject<{
338
+ family: z.ZodString;
339
+ against: z.ZodString;
340
+ matches: z.ZodNumber;
341
+ total: z.ZodNumber;
342
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodString>>;
343
+ }, z.core.$strict>>;
344
+ sets: z.ZodArray<z.ZodObject<{
345
+ gate: z.ZodString;
346
+ artifacts: z.ZodArray<z.ZodString>;
347
+ minCases: z.ZodNumber;
348
+ families: z.ZodDefault<z.ZodArray<z.ZodObject<{
349
+ id: z.ZodString;
350
+ minCases: z.ZodNumber;
351
+ }, z.core.$strict>>>;
352
+ }, z.core.$strict>>;
353
+ gaps: z.ZodString;
354
+ }, z.core.$strict>>;
236
355
  hard: z.ZodDefault<z.ZodBoolean>;
237
356
  feasibility: z.ZodOptional<z.ZodObject<{
238
357
  spike: z.ZodString;