devcontour-harness 0.1.0-alpha.12 → 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 +45 -2
- package/docs/architecture.md +6 -0
- package/docs/connectors.md +26 -0
- package/docs/contracts.md +100 -0
- package/docs/quickstart.md +1 -1
- package/docs/release-notes/0.1.0-alpha.13.md +91 -0
- package/docs/release-notes/0.1.0-alpha.14.md +69 -0
- package/docs/release-notes/0.1.0-alpha.15.md +62 -0
- package/docs/release-notes/0.1.0-alpha.16.md +36 -0
- package/docs/turbo-starter.md +2 -1
- package/docs/upgrade.md +15 -14
- package/examples/turbo-starter/setup.mjs +9 -2
- package/lib/connectors/files.js +2 -0
- package/lib/contracts/checks.d.ts +119 -0
- package/lib/contracts/checks.js +64 -1
- package/lib/contracts/execution.d.ts +28 -0
- package/lib/contracts/published.d.ts +28 -0
- package/lib/control/harness.js +2 -1
- package/lib/control/recovery.d.ts +25 -0
- package/lib/engine/runner.js +28 -3
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/integrations/connector/commands.d.ts +11 -4
- package/lib/integrations/connector/commands.js +16 -2
- package/lib/integrations/connector/config.d.ts +5 -0
- package/lib/integrations/connector/config.js +18 -1
- package/lib/integrations/connector/index.d.ts +1 -1
- package/lib/integrations/connector/index.js +1 -1
- package/lib/integrations/connector/snapshot.d.ts +22 -1
- package/lib/integrations/connector/snapshot.js +60 -3
- package/lib/integrations/connector/source.d.ts +4 -0
- package/lib/integrations/connector/source.js +1 -0
- package/lib/verification/acceptance.js +2 -1
- package/lib/verification/checks.d.ts +28 -0
- package/lib/verification/checks.js +270 -22
- package/lib/verification/corpus.d.ts +50 -0
- package/lib/verification/gates.js +14 -4
- package/lib/verification/property.d.ts +9 -0
- package/lib/verification/property.js +11 -2
- package/lib/verification/self-check.js +12 -12
- package/package.json +1 -1
- package/schemas/contract-document.schema.json +161 -0
- package/skills/harness-setup/SKILL.md +191 -69
- package/templates/controller-mode/README.md +5 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Headless-движок исполнения инженерных поручени
|
|
|
5
5
|
интеграция с принятой веткой через compare-and-swap и машинный результат с SHA
|
|
6
6
|
и доказательствами.
|
|
7
7
|
|
|
8
|
-
> Статус: `0.1.0-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.
|
|
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,49 @@ 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
|
+
|
|
156
|
+
## Выпуск 0.1.0-alpha.13
|
|
157
|
+
|
|
158
|
+
Controller mode для задач Relay и установка без лишних вопросов. Подробно —
|
|
159
|
+
[заметки выпуска](docs/release-notes/0.1.0-alpha.13.md).
|
|
160
|
+
|
|
161
|
+
- `tasks[].context` и `contextDir` коннектора: локальные пакеты контекста
|
|
162
|
+
(оверлей controller-mode) закрепляются в снимке задач Relay.
|
|
163
|
+
- Skill `harness-setup` решает рутинные выборы сам и спрашивает только на
|
|
164
|
+
развилках (вендоры writer/reviewer, недостающие факты Relay, изоляция,
|
|
165
|
+
Docker, конфликты с правилами проекта, коммит, запись в Relay, живые
|
|
166
|
+
вызовы); маршрут для pnpm/Turborepo-монорепо (Turbo Starter): свой
|
|
167
|
+
профиль, gates из команд проекта, controller mode.
|
|
168
|
+
|
|
126
169
|
## Выпуск 0.1.0-alpha.12
|
|
127
170
|
|
|
128
171
|
Skill установки и обновления. Подробно —
|
package/docs/architecture.md
CHANGED
|
@@ -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/connectors.md
CHANGED
|
@@ -109,14 +109,40 @@ CLI: 0 — успех, 2 — неверный вход, 3 — отказ/бло
|
|
|
109
109
|
| `projectId` | Ожидаемая идентичность проекта backend; несовпадение блокирует чтение снимка и любые мутации |
|
|
110
110
|
| `actor` | Автор всех записей коннектора |
|
|
111
111
|
| `stateDir` | Каталог состояния коннектора (относительно файла); без него — `--state` |
|
|
112
|
+
| `contextDir` | Каталог локальных пакетов контекста `tasks[].context` (относительно файла); по умолчанию `work/context` |
|
|
112
113
|
| `repository` | ID репозитория политики (и путь для сверки) |
|
|
113
114
|
| `tasks[]` | Задачи: `ref` (постоянный ID или ключ), роль, `writeScope`, `gates`, сопоставление критериев, обязательные документы |
|
|
114
115
|
| `tasks[].criteria[]` | Критерий (`id` или точный `title`) → `gate` и `testId` JUnit; `evidence: "gate"` — достаточно прошедшего gate (явный выбор) |
|
|
116
|
+
| `tasks[].context` | Локальные пакеты контекста поручения — каталоги `<contextDir>/<id>` (например, `controller-mode`); закрепляются в снимке |
|
|
115
117
|
| `completion` | `complete` — закрыть по правилам backend (по умолчанию в `done`); `review-only` — перевести в `review`/`column` и оставить человеку; `historicalComment` — при конфликте постановки записать явно исторический комментарий |
|
|
116
118
|
| `eligibility.columns` | Колонки, из которых задача допускается к запуску (`done`/`cancelled` — никогда) |
|
|
117
119
|
| `limits` | Пределы документов и постановки, число повторных чтений, срок владения доставкой |
|
|
118
120
|
| `history` | Запись истории работы (корневая и дочерние сессии) |
|
|
119
121
|
|
|
122
|
+
### Локальные пакеты контекста
|
|
123
|
+
|
|
124
|
+
`tasks[].context` добавляет к поручению задачи пакеты из `<contextDir>/<id>` —
|
|
125
|
+
те же каталоги, что у файлового графа: файлы вкладываются в запросы writer и
|
|
126
|
+
reviewer, `references/` закрепляется digest без вложения. Так к задачам Relay
|
|
127
|
+
подключается оверлей controller-mode
|
|
128
|
+
(`templates/controller-mode/`): `"context": ["controller-mode"]`.
|
|
129
|
+
|
|
130
|
+
- Пакеты закрепляются в `context.json` снимка; поручение получает
|
|
131
|
+
`context: [<контекст задачи>, ...пакеты]`. `source-snapshot` и manifest
|
|
132
|
+
называют их в `localContext` (ID, digest, число файлов и справок, байты).
|
|
133
|
+
- Digest пакетов и их распределение по задачам (какие у какой, в каком
|
|
134
|
+
порядке) входят в ревизию набора задач: изменённый, новый или перенесённый
|
|
135
|
+
пакет — новый `source-snapshot`, ревью плана и согласование (`run --source`
|
|
136
|
+
иначе отказывает `APPROVAL_STALE`). Semantic digest задачи от пакетов не
|
|
137
|
+
зависит: включение поля или изменение пакета не делает доставку уже
|
|
138
|
+
принятого результата конфликтом.
|
|
139
|
+
- Нет каталога или пакета — `NOT_READY` до чтения backend; пакет через
|
|
140
|
+
symlink — `INVALID_INPUT`. `source-check` называет то и другое в `problems`.
|
|
141
|
+
- Пределы контекста (файл, сумма, не больше 30 источников вместе с
|
|
142
|
+
контекстами задач) проверяются при снимке: превышение — `LIMIT_EXCEEDED`, и
|
|
143
|
+
задача не допускается к запуску.
|
|
144
|
+
- Без поля снимок, ревизия и digest задачи те же, что в прежних версиях.
|
|
145
|
+
|
|
120
146
|
### Идентичность и снимок
|
|
121
147
|
|
|
122
148
|
- Идентичность задачи — `<provider>:<projectId>:<постоянный ID>`; ID поручения
|
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` хранит транзакционно:
|
package/docs/quickstart.md
CHANGED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# devcontour-harness 0.1.0-alpha.13
|
|
2
|
+
|
|
3
|
+
Controller mode для задач Relay и маршрут установки, который спрашивает только
|
|
4
|
+
на развилках. Gates, `maxAttempts`, бюджеты попыток и повторов, правила
|
|
5
|
+
находок, изоляция, принятие target ref и формат состояния не менялись.
|
|
6
|
+
|
|
7
|
+
## Что нового
|
|
8
|
+
|
|
9
|
+
- **`tasks[].context` и `contextDir` коннектора.** Задача Relay получает,
|
|
10
|
+
кроме своего контекста, локальные пакеты из `<contextDir>/<id>` (по
|
|
11
|
+
умолчанию `work/context` рядом с `connector.json`) — например, оверлей
|
|
12
|
+
controller-mode из `templates/controller-mode/`. Пакет закрепляется в
|
|
13
|
+
`context.json` снимка теми же правилами, что файловый контекст графа
|
|
14
|
+
(`references/` — справки без вложения). Digest пакетов и их распределение
|
|
15
|
+
по задачам входят в ревизию набора задач: изменённый пакет требует нового `source-snapshot` и
|
|
16
|
+
согласования (`run --source` иначе отказывает `APPROVAL_STALE`). Semantic
|
|
17
|
+
digest задачи от пакетов не зависит: включение поля или изменение пакета не
|
|
18
|
+
делает доставку принятого результата конфликтом. Нет каталога или пакета —
|
|
19
|
+
`NOT_READY` до чтения backend; `source-check` называет его в `problems`
|
|
20
|
+
([connectors](../connectors.md#локальные-пакеты-контекста)).
|
|
21
|
+
- **Пределы контекста при снимке.** `source-snapshot` проверяет пределы
|
|
22
|
+
снимка контекста (размер файла, сумма, не больше 30 источников) и сообщает
|
|
23
|
+
превышение как `LIMIT_EXCEEDED`, а не только отказом при запуске;
|
|
24
|
+
`source-check` проверяет пределы локальных пакетов. Вывод
|
|
25
|
+
`source-snapshot` и manifest называют закреплённые пакеты (`localContext`).
|
|
26
|
+
- **`controllerContext`** (`examples/turbo-starter/setup.mjs`) пересобирает
|
|
27
|
+
пакет с пустого каталога и не берёт в справки `.harness/` и сам каталог
|
|
28
|
+
пакета: повторная сборка внутри репозитория не вкладывает копии пакета и
|
|
29
|
+
не оставляет справки удалённых AGENTS.md. `upstream: null` — сборка для
|
|
30
|
+
обычного репозитория проекта.
|
|
31
|
+
- **Skill `harness-setup`:**
|
|
32
|
+
- таблица «решить или спросить»: рутинные выборы (ветка, каталог
|
|
33
|
+
установки, источник пакета, профиль, gates, согласование, completion)
|
|
34
|
+
агент делает сам и объясняет в отчёте; спрашивает о вендорах
|
|
35
|
+
writer/reviewer, ревью тем же вендором, controller mode (оверлей
|
|
36
|
+
главнее правил продукта), пропуске проверки проекта или CI, недостающих
|
|
37
|
+
фактах Relay, изоляции, Docker, конфликтах с правилами проекта, коммите,
|
|
38
|
+
записи в Relay и живых вызовах;
|
|
39
|
+
- pnpm/Turborepo-монорепо (Turbo Starter): локальный `.harness/profile.json`
|
|
40
|
+
из команд проекта (`pnpm --filter`), test-gates с JUnit без новых
|
|
41
|
+
зависимостей или приёмочные проверки в `.harness/acceptance/`, gate
|
|
42
|
+
детерминизма генерации, защищённые пути, среда с Docker только по
|
|
43
|
+
согласию;
|
|
44
|
+
- controller mode: пакет собирается `controllerContext`, в Git не
|
|
45
|
+
коммитится (`.git/info/exclude`, пересборка в новом клоне) и
|
|
46
|
+
подключается к файловым графам и к задачам Relay (`tasks[].context`);
|
|
47
|
+
- при обновлении — предложить новые возможности выпуска, не применяя их.
|
|
48
|
+
|
|
49
|
+
## Изменения договора
|
|
50
|
+
|
|
51
|
+
Добавления в конфигурацию коннектора: `contextDir` (строка) и
|
|
52
|
+
`tasks[].context` (1–10 ID); в manifest снимка и ответ `source-snapshot` —
|
|
53
|
+
`localContext` (только при пакетах). Без них снимок, ревизия набора, semantic
|
|
54
|
+
digest задачи, digest графа и контекста те же, что в alpha.12. Пакет с именем
|
|
55
|
+
вида ID контекста задачи (`c` + 20 hex) — `INVALID_INPUT`.
|
|
56
|
+
|
|
57
|
+
Изменение отказа: корень источника контекста через symlink (в файловом
|
|
58
|
+
графе и в пакетах коннектора) — `INVALID_INPUT` «Контекст не читается через
|
|
59
|
+
symlink» вместо `NOT_READY` «не найден»; symlink внутри источника и раньше
|
|
60
|
+
давал `INVALID_INPUT`.
|
|
61
|
+
|
|
62
|
+
## Совместимость
|
|
63
|
+
|
|
64
|
+
Формат состояния не менялся: alpha.13 читает всё, что читает alpha.12, а
|
|
65
|
+
alpha.12 — всё, что пишет alpha.13. Конфигурация коннектора с новыми полями
|
|
66
|
+
alpha.12 не принимает (строгая схема). Обновление и откат — по
|
|
67
|
+
[upgrade](../upgrade.md).
|
|
68
|
+
|
|
69
|
+
## Проверка выпуска
|
|
70
|
+
|
|
71
|
+
`npm run check` (lint, typecheck, schemas, build, весь набор тестов, package
|
|
72
|
+
smoke из установленного архива) на macOS arm64, Node.js 24.3. Тесты
|
|
73
|
+
коннектора на подделке backend (`tests/connector-context.test.ts`):
|
|
74
|
+
|
|
75
|
+
- пакет закреплён в снимке и поручении, его байты в контексте попытки
|
|
76
|
+
writer; поручение принято и доставлено;
|
|
77
|
+
- без поля ревизия набора, digest задачи, графа и контекста совпадают со
|
|
78
|
+
значениями alpha.12 (golden-тест, сверен с кодом тега);
|
|
79
|
+
- изменённый пакет — `APPROVAL_STALE` до запуска; перенос пакета между
|
|
80
|
+
задачами и смена порядка — новая ревизия; больше 30 источников —
|
|
81
|
+
`LIMIT_EXCEEDED`; доставка принятого
|
|
82
|
+
результата после изменения пакета и после включения поля — не конфликт;
|
|
83
|
+
- нет каталога — отказ без обращений к backend; нет пакета, свой
|
|
84
|
+
`contextDir`, конфликт имени, symlink-пакет, превышение пределов в снимке
|
|
85
|
+
и `source-check`, `localContext` в manifest.
|
|
86
|
+
|
|
87
|
+
Пересборка `controllerContext` после коммита пакета и удаления AGENTS.md —
|
|
88
|
+
`tests/starter-setup.test.ts`. Тест skill сверяет команды, флаги,
|
|
89
|
+
обязательные аргументы и пути `<pkg>/…` с поставкой. Живые модели и
|
|
90
|
+
настоящие Relay не вызывались; W01 на настоящих Relay для alpha.13 не
|
|
91
|
+
повторялся.
|
|
@@ -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/turbo-starter.md
CHANGED
|
@@ -224,7 +224,8 @@ controller. Оверлей `templates/controller-mode/AGENTS.controller.md` v1
|
|
|
224
224
|
читает живые файлы своего worktree;
|
|
225
225
|
- `context/controller-mode/provenance.json` содержит версию и sha256
|
|
226
226
|
оверлея, baseline SHA и blob каждого product AGENTS.md;
|
|
227
|
-
- в каждом поручении указан `"context": ["controller-mode"]
|
|
227
|
+
- в каждом поручении указан `"context": ["controller-mode"]`; для задач
|
|
228
|
+
Relay — в `tasks[].context` коннектора ([connectors](connectors.md#локальные-пакеты-контекста)).
|
|
228
229
|
|
|
229
230
|
Оверлей перечисляет правила, делегированные controller-у: worktree, commit,
|
|
230
231
|
merge, история Relay, `pnpm run setup`, вложенные оркестраторы и `harness`.
|
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
|
|
25
|
-
| ------------------------------------------------------------------------------ | ------------------------ | ------------------------ | ----------------------- |
|
|
26
|
-
| standalone `stateVersion: 1` версией alpha.1 | да | да | да | да
|
|
27
|
-
| хост, центральная база | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер)
|
|
28
|
-
| хост, базы компонентов | да (через адаптер) | да (через адаптер) | да (через адаптер) | да (через адаптер)
|
|
29
|
-
| alpha.2 после штатной остановки controller | да | да | да | да
|
|
30
|
-
| alpha.2 с живой или брошенной ролью controller | **нет**, отказ до записи | да | да | да
|
|
31
|
-
| alpha.4 с совместной проверкой | **нет**, отказ до записи | **нет**, отказ до записи | да | да
|
|
32
|
-
| alpha.6 standalone с записями ревью нового протокола или доставкой `uncertain` | **нет**, отказ до записи | **нет**, отказ до записи | да | да
|
|
33
|
-
| alpha.6, хост DevContour (адаптер alpha.4) | — | — | да (через адаптер) | да (через адаптер)
|
|
34
|
-
| alpha.7 с новым `inspection` ревью кода | не проверялось | не проверялось | **нет** (строгая схема) | да
|
|
35
|
-
|
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|