devcontour-harness 0.1.0-alpha.13 → 0.1.0-alpha.18
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 +48 -2
- package/docs/architecture.md +77 -3
- package/docs/contracts.md +100 -0
- package/docs/quickstart.md +1 -1
- 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/release-notes/0.1.0-alpha.17.md +86 -0
- package/docs/release-notes/0.1.0-alpha.18.md +48 -0
- package/docs/review-probes.md +9 -3
- package/docs/review-protocol.md +9 -0
- package/docs/upgrade.md +16 -14
- package/lib/agents/cli-adapter.js +14 -10
- package/lib/agents/review-probe.d.ts +9 -0
- package/lib/agents/review-probe.js +23 -1
- package/lib/agents/schemas.d.ts +206 -0
- package/lib/agents/schemas.js +37 -1
- package/lib/agents/usage.d.ts +22 -0
- package/lib/agents/usage.js +112 -6
- package/lib/contracts/checks.d.ts +119 -0
- package/lib/contracts/checks.js +64 -1
- package/lib/contracts/cli.d.ts +30 -0
- package/lib/contracts/diagnosis.d.ts +3 -1
- package/lib/contracts/diagnosis.js +2 -0
- package/lib/contracts/events.d.ts +12 -0
- package/lib/contracts/execution.d.ts +109 -5
- package/lib/contracts/execution.js +58 -0
- package/lib/contracts/failure.d.ts +17 -3
- package/lib/contracts/failure.js +4 -2
- package/lib/contracts/published.d.ts +67 -1
- package/lib/contracts/repair-policy.d.ts +7 -0
- package/lib/contracts/repair-policy.js +17 -0
- package/lib/contracts/review.d.ts +12 -0
- package/lib/contracts/review.js +19 -0
- package/lib/control/harness.d.ts +2 -2
- package/lib/control/harness.js +2 -1
- package/lib/control/recovery.d.ts +26 -1
- package/lib/engine/engine.d.ts +41 -14
- package/lib/engine/engine.js +92 -8
- package/lib/engine/failure.d.ts +1 -1
- package/lib/engine/failure.js +1 -1
- package/lib/engine/property-recovery.d.ts +1 -0
- package/lib/engine/property-recovery.js +4 -1
- package/lib/engine/repair.d.ts +26 -0
- package/lib/engine/repair.js +83 -1
- package/lib/engine/runner.d.ts +7 -0
- package/lib/engine/runner.js +207 -34
- package/lib/explain/state.js +4 -2
- package/lib/index.d.ts +6 -4
- package/lib/index.js +6 -4
- package/lib/projections/stop.d.ts +1 -1
- package/lib/projections/stop.js +16 -0
- package/lib/storage/document.d.ts +48 -8
- package/lib/verification/acceptance.js +2 -1
- package/lib/verification/already-satisfied.d.ts +44 -0
- package/lib/verification/already-satisfied.js +49 -0
- 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/gate-scope.d.ts +36 -0
- package/lib/verification/gate-scope.js +97 -0
- package/lib/verification/gates-at.d.ts +67 -0
- package/lib/verification/gates-at.js +173 -0
- package/lib/verification/gates.d.ts +5 -0
- package/lib/verification/gates.js +20 -5
- 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/schemas/execution-document.schema.json +134 -0
- package/schemas/run-event.schema.json +4 -0
- package/schemas/stop-diagnosis.schema.json +2 -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.18` — предварительный выпуск (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.18 # точная версия
|
|
32
32
|
# или: npm install --save-exact devcontour-harness@alpha # текущая alpha
|
|
33
33
|
npx harness --version
|
|
34
34
|
```
|
|
@@ -123,6 +123,52 @@ PASS» нет. Адаптеры хоста реализуют порты `Execut
|
|
|
123
123
|
`devcontour-harness/schemas/<имя>.schema.json`. Декларации используют типы
|
|
124
124
|
Node.js: TypeScript-потребителю нужен `@types/node` (или `skipLibCheck`).
|
|
125
125
|
|
|
126
|
+
## Выпуск 0.1.0-alpha.18
|
|
127
|
+
|
|
128
|
+
`runGatesAt` исполняет gates с предпосылками профиля: явный `dependsOn` или,
|
|
129
|
+
в профиле без него, более ранние check gates (установка); общий с попыткой
|
|
130
|
+
порядок `orderedScope`; все провалы — сразу; `dependsOn: []` — без
|
|
131
|
+
предпосылок. Подробно — [заметки выпуска](docs/release-notes/0.1.0-alpha.18.md).
|
|
132
|
+
|
|
133
|
+
## Выпуск 0.1.0-alpha.17
|
|
134
|
+
|
|
135
|
+
Меньше слепых повторов: reviewer называет класс входов, два отказа ревью по
|
|
136
|
+
одному свойству и классу — пробел приёмки с остановкой; отказы окружения не
|
|
137
|
+
тратят попытки (свой предел), штатная остановка возвращает работу в очередь,
|
|
138
|
+
`completed: false` повторяется с черновика; пустой результат принимается
|
|
139
|
+
только с механическим основанием (иначе `needs-lead`), `runGatesAt` проверяет
|
|
140
|
+
gates на закреплённом SHA; стоимость вызова учитывается по всему потоку. Подробно — [заметки выпуска](docs/release-notes/0.1.0-alpha.17.md).
|
|
141
|
+
|
|
142
|
+
## Выпуск 0.1.0-alpha.16
|
|
143
|
+
|
|
144
|
+
Отказ по файлу эталонного набора — только по строковому литералу, без ложных
|
|
145
|
+
отказов на комментариях и похожих именах; reviewer контракта видит минимумы
|
|
146
|
+
семейств. Подробно — [заметки выпуска](docs/release-notes/0.1.0-alpha.16.md);
|
|
147
|
+
alpha.14 и alpha.15 — локальные выпуски, в npm не публиковались.
|
|
148
|
+
|
|
149
|
+
## Выпуск 0.1.0-alpha.15
|
|
150
|
+
|
|
151
|
+
Эталонные наборы защищены от подгонки. Подробно —
|
|
152
|
+
[заметки выпуска](docs/release-notes/0.1.0-alpha.15.md); alpha.14 — локальный
|
|
153
|
+
выпуск, в npm не публиковался.
|
|
154
|
+
|
|
155
|
+
- Writer и reviewer кода знают файлы эталонных наборов; кандидат, чей
|
|
156
|
+
изменённый файл называет файл набора, отклоняется до gates.
|
|
157
|
+
- `crossChecks[].artifacts`: закреплённый скрипт или журнал сверки эталона.
|
|
158
|
+
- Обязательство, которое поручение выбрать не может, отклоняется сразу; ID
|
|
159
|
+
testcase node:test (`test.<имя>`) описан и подсказан в отказе.
|
|
160
|
+
|
|
161
|
+
## Выпуск 0.1.0-alpha.14
|
|
162
|
+
|
|
163
|
+
Проверка по закреплённым эталонным наборам. Подробно —
|
|
164
|
+
[заметки выпуска](docs/release-notes/0.1.0-alpha.14.md).
|
|
165
|
+
|
|
166
|
+
- `verification: "reference"` в договоре проверки: обещание проверяется
|
|
167
|
+
наборами ответов независимого эталона, закреплёнными артефактами контракта;
|
|
168
|
+
gate без генератора подтверждает отчётом свою долю входов и семейств.
|
|
169
|
+
- `obligations[].gates`: обязательство исполняют несколько gates.
|
|
170
|
+
- Reviewer контракта видит пределы наборов (`gaps`) и сверку эталона.
|
|
171
|
+
|
|
126
172
|
## Выпуск 0.1.0-alpha.13
|
|
127
173
|
|
|
128
174
|
Controller mode для задач Relay и установка без лишних вопросов. Подробно —
|
package/docs/architecture.md
CHANGED
|
@@ -185,6 +185,49 @@ runtime-граф пакета.
|
|
|
185
185
|
- **Покрытие gates.** `uncoveredGates` засчитывает только evidence попыток под
|
|
186
186
|
текущим основанием политики: тот же ID gate с другой командой — другая
|
|
187
187
|
проверка.
|
|
188
|
+
- **Пауза по классу отказа.** Отказ класса с `blocksQueue`
|
|
189
|
+
(`provider-auth`, `environment`) в той же транзакции ставит паузу
|
|
190
|
+
`runtime` и добавляет класс в `pauseFailures`: новых выдач нет ни одной
|
|
191
|
+
задаче. Отказ окружения до кандидата (`blocked`) попытку не засчитывает.
|
|
192
|
+
Снимает паузу `clearFailure([класс])` — его вызывает восстановление,
|
|
193
|
+
назначившее повтор (у DevContour — цикл board workflow, той же транзакцией,
|
|
194
|
+
что повтор), — или `resume` человека; выдача возвращается, когда в списке не
|
|
195
|
+
осталось классов. Поэтому разовый отказ окружения под циклом восстановления
|
|
196
|
+
останавливает выдачу только до его следующего шага, а без цикла пауза стоит
|
|
197
|
+
до решения человека. Пауза человека этим не снимается.
|
|
198
|
+
- **Gates на SHA вне попытки.** `runGatesAt` исполняет названные gates
|
|
199
|
+
компонента на закреплённом SHA так же, как integration поручения:
|
|
200
|
+
отдельное рабочее дерево, снимки зависимостей, ресурсы, lifecycle и
|
|
201
|
+
prepare, окружение фазы `integration`, песочница и `runGate`. Область —
|
|
202
|
+
названные gates и предпосылки каждого (`standaloneScope`), порядок — тот же
|
|
203
|
+
`orderedScope`, что у попытки. Предпосылки (`gatePrerequisites`): у gate с
|
|
204
|
+
объявленным `dependsOn` (в том числе пустым — режим графа) — замыкание по
|
|
205
|
+
`dependsOn`; у gate без поля `dependsOn` (профиль в режиме порядка массива)
|
|
206
|
+
— все более ранние gates вида `check` с их предпосылками: установка,
|
|
207
|
+
сборка, статические проверки. Более ранние test gates не добавляются;
|
|
208
|
+
каждый gate посещается один раз. Задаче эти предпосылки называть
|
|
209
|
+
по-прежнему приходится явно: её область исполняется как записана. Провал
|
|
210
|
+
gate не останавливает проверку. Пропускается только gate, чья явная
|
|
211
|
+
предпосылка (`dependsOn`) не прошла; провал неявной (раннего check gate)
|
|
212
|
+
тесты не пропускает — названы оба (`failures`). Evidence (`test`,
|
|
213
|
+
`integration`, этот SHA) пишется через запись хоста до следующего gate;
|
|
214
|
+
дерево обязано остаться на SHA без изменений.
|
|
215
|
+
- **Пустой результат.** Исполнитель, не изменивший ни файла, не получает
|
|
216
|
+
отказ сразу: кандидат — сама база (без коммита), gates поручения идут на
|
|
217
|
+
ней, а reviewer обеих фаз получает схему ответа с обязательным
|
|
218
|
+
`alreadySatisfied` (gates области задачи — хотя бы один test gate и все
|
|
219
|
+
проверки договоров поручения — и основание). Подтверждения reviewer мало:
|
|
220
|
+
нужно механическое основание, которое находит controller
|
|
221
|
+
(`alreadySatisfiedVerdict`): договор проверки поручения, все gates которого
|
|
222
|
+
в области задачи и названы, или зависимость поручения, чей принятый
|
|
223
|
+
результат входит в SHA, а собственный кандидат изменил файлы области записи
|
|
224
|
+
поручения. Без основания — `needs-lead` (остановка, решение ведущего): общий
|
|
225
|
+
зелёный тест на базе новой работы не доказывает. Без годного подтверждения,
|
|
226
|
+
при отклонении ревью или красном gate на базе — `empty-result`. С
|
|
227
|
+
основанием поручение принимается без нового коммита; основание пишется в
|
|
228
|
+
evidence ревью (`alreadySatisfied.basis`), и `engine.finish` повторяет
|
|
229
|
+
правило целиком по записанному, сверяя основание по зависимости с её
|
|
230
|
+
принятой попыткой.
|
|
188
231
|
- **Область записи.** Изменения вне `writeScope`, защищённых путей и
|
|
189
232
|
закреплённого контекста отклоняют попытку до интеграции.
|
|
190
233
|
- **Gates.** Тестовый gate принимается по свежему непустому отчёту без
|
|
@@ -217,11 +260,32 @@ runtime-граф пакета.
|
|
|
217
260
|
исполнение, завершено) сохраняется и переживает рестарт; владелец задания
|
|
218
261
|
fenced. Упавшее поручение повторяется только по записанному классу отказа:
|
|
219
262
|
в пределах повторов одинакового отпечатка для класса, попыток поручения
|
|
220
|
-
(`maxAttempts`) и бюджета восстановлений задания (`repairBudget`).
|
|
263
|
+
(`maxAttempts`) и бюджета восстановлений задания (`repairBudget`). Отказ
|
|
264
|
+
окружения или провайдера (и истёкшее владение) попытку поручения не
|
|
265
|
+
засчитывает, даже после кандидата: о работе он ничего не говорит; повторы
|
|
266
|
+
таких отказов ограничены паузой выдачи, пределом одинаковых отпечатков,
|
|
267
|
+
`repairBudget` и своим пределом на поручение (`MAX_NEUTRAL_FAILURES` = 3,
|
|
268
|
+
счётчик `neutralFailures`): на нём `retry` без сброса, выдача и
|
|
269
|
+
восстановление отказывают; сброс человека обнуляет счётчик. Попытка, прерванная штатной остановкой (`Runner.stop`),
|
|
270
|
+
не падает: черновик сохраняется, попытка помечается `interrupted:
|
|
271
|
+
shutdown`, поручение возвращается в очередь (`ready`) без траты попытки и
|
|
272
|
+
без паузы по классу; после снятия паузы остановки она продолжается с
|
|
273
|
+
кандидата или черновика. Интегрированная попытка так не возвращается.
|
|
274
|
+
Решение и
|
|
221
275
|
списание бюджета — одна транзакция с повтором. Отказ провайдера, отмена,
|
|
222
276
|
неизвестный класс и устаревшая база — остановка с причиной. Восстановление
|
|
223
277
|
снимает только свою причину паузы; паузу человека не снимает. Режим
|
|
224
|
-
`operator` автоматических повторов не делает.
|
|
278
|
+
`operator` автоматических повторов не делает. Тексты отказов ревью от
|
|
279
|
+
попытки к попытке разные, поэтому сверх отпечатка считается и названное:
|
|
280
|
+
два отказа ревью подряд по одному необъявленному свойству с тем же классом
|
|
281
|
+
входов (`classified`; класс сравнивается без регистра и лишних пробелов) —
|
|
282
|
+
пробел приёмки (`acceptanceGap`), остановка с `gap` и причиной для ведущего
|
|
283
|
+
вместо третьей слепой попытки. Совпадение только свойства или только класса
|
|
284
|
+
(`unboundProperties`, `inputClasses`) — слабее: общий класс бывает у разных
|
|
285
|
+
дефектов, поэтому нужно три отказа подряд.
|
|
286
|
+
Счёт — как у эпизода свойства: отказ окружения его не меняет, отказ gate,
|
|
287
|
+
другое название или новое основание поручения обрывают серию. Объявленные
|
|
288
|
+
свойства ведёт эпизод разбора.
|
|
225
289
|
- **Переиспользование кандидата.** После отказа окружения или по времени,
|
|
226
290
|
когда кандидат уже был, повтор берёт его вместо новой реализации, только
|
|
227
291
|
если совпадают все основания: постановка, контракты, политика, runtime и
|
|
@@ -267,6 +331,12 @@ runtime-граф пакета.
|
|
|
267
331
|
и файлы, не совпадающие с целевой веткой, отклоняются до вызова reviewer.
|
|
268
332
|
Поручение включает механизм полем `properties`; свойства, которых нет в его
|
|
269
333
|
договорах или которые исполняет не генеративный gate, не согласуются.
|
|
334
|
+
Обязательство может назвать несколько gates (`gates`) и способ
|
|
335
|
+
`reference`: сверку с закреплёнными эталонными наборами вместо генератора.
|
|
336
|
+
Gate эталонных наборов получает путь отчёта свойств и без `property` и
|
|
337
|
+
обязан подтвердить свою долю входов и семейств; пределы наборов (`gaps`)
|
|
338
|
+
reviewer контракта видит отдельно
|
|
339
|
+
([договор](contracts.md#способы-исполнения-обязательства-property-и-reference)).
|
|
270
340
|
Генеративный gate получает seed controller (`DEVCONTOUR_SEED`, свой у
|
|
271
341
|
попытки, фазы и gate), селектор свойств и закреплённый корпус; отчёт
|
|
272
342
|
свойств читается при любом исходе из каталога вне worktree. Gate проходит,
|
|
@@ -392,7 +462,11 @@ runtime-граф пакета.
|
|
|
392
462
|
reviewer — получает последние 20 входов с ожиданием, наблюдением и командой.
|
|
393
463
|
Это диагностика: gate не расширяет и корпусом не становится без
|
|
394
464
|
подтверждения эталоном; обязательный корпус от ограничения реестра не
|
|
395
|
-
зависит.
|
|
465
|
+
зависит. Блокирующая находка со входом называет и нарушенное свойство или
|
|
466
|
+
критерий (`property`), и класс входов (`inputClass`) — генератор или
|
|
467
|
+
семейство, к которому относится пример. Класс записывается в реестр и на
|
|
468
|
+
отклонённую попытку (`inputClasses`); следующий writer получает задачу
|
|
469
|
+
чинить класс, а не экземпляр.
|
|
396
470
|
- **Контекст плана и согласование.** Снимок контекста хранится по digest, а
|
|
397
471
|
действующим становится только вместе с согласованием графа
|
|
398
472
|
(`approval.context`). Пока новый снимок на ревью, после его отклонения,
|
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,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
|
+
реализации обнаружены. Живые модели не вызывались.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# devcontour-harness 0.1.0-alpha.17
|
|
2
|
+
|
|
3
|
+
Меньше слепых повторов и ручных сбросов. Включает всё из
|
|
4
|
+
[0.1.0-alpha.16](0.1.0-alpha.16.md). Gates, правила находок, изоляция,
|
|
5
|
+
принятие target ref и `maxAttempts` не менялись; формат состояния получил
|
|
6
|
+
необязательные поля (ниже, «Совместимость»).
|
|
7
|
+
|
|
8
|
+
## Что нового
|
|
9
|
+
|
|
10
|
+
- **Класс входов в находке ревью.** Блокирующая находка со входом называет
|
|
11
|
+
нарушенное свойство или критерий (`reproduction.property`) и класс входов
|
|
12
|
+
(`reproduction.inputClass`) — генератор или семейство, а не экземпляр. Поле
|
|
13
|
+
обязательно в схеме ответа runtime; ответ прежней формы без него
|
|
14
|
+
разбирается. Класс пишется в реестр воспроизведений и на отклонённую
|
|
15
|
+
попытку (`inputClasses`, пары `classified`); следующий writer получает
|
|
16
|
+
задачу чинить класс.
|
|
17
|
+
- **Пробел приёмки.** `repairDecision` останавливает поручение с полем `gap`
|
|
18
|
+
и причиной для ведущего, когда два отказа ревью подряд называют одно и то
|
|
19
|
+
же необъявленное свойство с тем же классом входов (класс без регистра и
|
|
20
|
+
лишних пробелов). Совпадение только свойства или только класса требует
|
|
21
|
+
трёх отказов подряд: общий класс бывает у разных дефектов. Отказ
|
|
22
|
+
окружения серию не меняет; отказ gate, другое название и новое основание
|
|
23
|
+
поручения её обрывают. `explain` показывает то же. Объявленные свойства
|
|
24
|
+
по-прежнему ведёт эпизод разбора.
|
|
25
|
+
- **Отказы окружения не тратят попытки.** Отказ окружения или провайдера и
|
|
26
|
+
истёкшее владение не засчитываются в `maxAttempts`, и после кандидата.
|
|
27
|
+
Предел у них свой: `MAX_NEUTRAL_FAILURES` = 3 на поручение (счётчик
|
|
28
|
+
`neutralFailures`); на нём `retry` без сброса, выдача и восстановление
|
|
29
|
+
отказывают, сброс человека обнуляет счётчик.
|
|
30
|
+
- **Штатная остановка не роняет работу.** `Runner.stop` помечает свои
|
|
31
|
+
попытки: прерванная сохраняет черновик, получает `interrupted: shutdown`,
|
|
32
|
+
а поручение возвращается в очередь (`ready`) без траты попытки и без паузы
|
|
33
|
+
по классу отказа; после снятия паузы остановки следующая попытка
|
|
34
|
+
продолжает с кандидата или черновика. Интегрированная попытка так не
|
|
35
|
+
возвращается: это обычный отказ, хост получает `hooks.failed`.
|
|
36
|
+
- **Класс отказа `unfinished`.** `completed: false` исполнителя был
|
|
37
|
+
`unknown` и останавливал работу без повтора, с сохранённым черновиком.
|
|
38
|
+
Теперь это `unfinished`: повтор (предел одинаковых — 2) продолжает с
|
|
39
|
+
черновика (`continuedFrom.kind: unfinished`) в пределах `maxAttempts` и
|
|
40
|
+
`repairBudget`; для эпизода свойства отказ нейтрален.
|
|
41
|
+
- **Пустой результат только с механическим основанием.** Пустая реализация
|
|
42
|
+
больше не отклоняется сразу: кандидат — сама база, gates задачи идут на
|
|
43
|
+
ней, оба ревью отвечают схемой с обязательным `alreadySatisfied` (gates
|
|
44
|
+
области задачи — хотя бы один test gate и все gates договоров проверки
|
|
45
|
+
поручения — и основание). Принятие требует ещё механического основания,
|
|
46
|
+
которое находит controller: договор проверки поручения со всеми gates в
|
|
47
|
+
области задачи, или зависимость, чей принятый результат входит в
|
|
48
|
+
проверяемый SHA и чей кандидат менял файлы области записи поручения.
|
|
49
|
+
Основание пишется в evidence ревью (`alreadySatisfied.basis`). Без него —
|
|
50
|
+
новый класс отказа `needs-lead`: остановка без повтора, решение ведущего.
|
|
51
|
+
`engine.finish` повторяет правило целиком по записанным данным.
|
|
52
|
+
- **`runGatesAt`.** Именованные gates компонента (с предпосылками) на
|
|
53
|
+
закреплённом SHA вне попытки — тем же путём, что интеграция задачи: свой
|
|
54
|
+
worktree, снимки зависимостей, ресурсы, lifecycle и prepare, окружение
|
|
55
|
+
интеграции, песочница проверок; каждый evidence — через callback хоста,
|
|
56
|
+
первый провал останавливает прогон, дерево должно остаться прежним.
|
|
57
|
+
- **Учёт стоимости по всему потоку.** Адаптер CLI разбирает stdout по
|
|
58
|
+
строкам по мере поступления и хранит только поля телеметрии (последний
|
|
59
|
+
`result` claude, `turn.completed` codex, первая названная модель): цена
|
|
60
|
+
длинного вызова больше не теряется за пределом хвоста вывода. Разбор
|
|
61
|
+
ограничен по памяти и не бросает исключений из обработчика вывода.
|
|
62
|
+
- **Отчёт свойств в пробах ревьюера.** Проба gate получает путь отчёта
|
|
63
|
+
свойств в scratch controller (`HARNESS_PROPERTY_REPORT`,
|
|
64
|
+
`DEVCONTOUR_PROPERTY_REPORT` — та же переменная, что у движка) и сохраняет
|
|
65
|
+
копию отчёта как evidence пробы; отчёт-ссылка отклоняется.
|
|
66
|
+
|
|
67
|
+
## Совместимость
|
|
68
|
+
|
|
69
|
+
Новые необязательные поля попытки (`interrupted`, `inputClasses`,
|
|
70
|
+
`classified`), поручения (`neutralFailures`), записи воспроизведения
|
|
71
|
+
(`inputClass`), evidence ревью (`alreadySatisfied`) и классы отказа
|
|
72
|
+
`unfinished` и `needs-lead`; в схемах данных CLI это единственные
|
|
73
|
+
аддитивные изменения перечней. Прежние записи не меняются.
|
|
74
|
+
Строгие схемы прежних версий новых значений не знают: после первой записи
|
|
75
|
+
alpha.17 откат — только через копию. Изменение поведения: тесты хоста,
|
|
76
|
+
ждавшие засчитанную попытку после отказа окружения или `failed` после
|
|
77
|
+
штатной остановки, нужно обновить. Матрица — [upgrade](../upgrade.md).
|
|
78
|
+
|
|
79
|
+
## Проверка выпуска
|
|
80
|
+
|
|
81
|
+
`npm run check` на macOS arm64, Node.js 24.3. Новые тесты на fixture runtime
|
|
82
|
+
и реальных Git-фикстурах (`repair`, `reproductions`, `runner` T14,
|
|
83
|
+
`explain-engine`, `network-recovery`, `reuse`, `usage`, `probe-gates`,
|
|
84
|
+
`already-satisfied`, `gates-at`); каждый новый тест обнаруживает свой мутант
|
|
85
|
+
реализации. Закрепление схем данных CLI (H3-01) сверяет байты H2 без
|
|
86
|
+
аддитивных значений `unfinished` и `needs-lead`. Живые модели не вызывались.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# devcontour-harness 0.1.0-alpha.18
|
|
2
|
+
|
|
3
|
+
Проверка gates на закреплённом SHA исполняет их с теми предпосылками, на
|
|
4
|
+
которые опирается профиль. Включает всё из [0.1.0-alpha.17](0.1.0-alpha.17.md).
|
|
5
|
+
Формат состояния, gates попыток, правила находок, изоляция, принятие target
|
|
6
|
+
ref и `maxAttempts` не менялись.
|
|
7
|
+
|
|
8
|
+
## Что нового
|
|
9
|
+
|
|
10
|
+
- **Предпосылки проверки вне задачи.** `runGatesAt` брал только явные
|
|
11
|
+
`dependsOn`. В профиле, который опирается на порядок массива (установка
|
|
12
|
+
первой, без `dependsOn`), проверка одного test gate шла без установки и
|
|
13
|
+
падала на отсутствующих модулях, хотя задачи проходили: их область называла
|
|
14
|
+
установку явно. Теперь область проверки — названные gates и предпосылки
|
|
15
|
+
каждого (`standaloneScope`), порядок — тот же `orderedScope`, что у попытки
|
|
16
|
+
(прежний внутренний `ordered` runner, без изменения поведения).
|
|
17
|
+
Предпосылки (`gatePrerequisites`): у gate с объявленным `dependsOn` —
|
|
18
|
+
замыкание по `dependsOn`; у gate без поля `dependsOn` — все более ранние
|
|
19
|
+
gates вида `check` со своими предпосылками. Более ранние test gates не
|
|
20
|
+
добавляются. Каждый gate посещается один раз, поэтому `dependsOn` на более
|
|
21
|
+
поздний gate вместе с неявным ребром не зацикливается. Область задачи
|
|
22
|
+
по-прежнему исполняется как записана.
|
|
23
|
+
- **Явный `dependsOn: []` — без предпосылок.** Объявленный пустой
|
|
24
|
+
`dependsOn` — режим графа: неявных предпосылок нет. Порядок массива
|
|
25
|
+
действует только для gate без поля.
|
|
26
|
+
- **Все провалы сразу.** Провал gate больше не останавливает проверку:
|
|
27
|
+
исполняются все названные gates, результат перечисляет каждый непрошедший
|
|
28
|
+
(`failures`; `failure` — первый, как раньше). Пропускается только gate,
|
|
29
|
+
чья явная предпосылка (`dependsOn`, `explicitPrerequisites`) не прошла, — он
|
|
30
|
+
назван с этой причиной. Провал неявной предпосылки (раннего check gate) не
|
|
31
|
+
скрывает исход тестов: исполняются и названы оба. Evidence по-прежнему
|
|
32
|
+
пишется через запись хоста и привязано к SHA.
|
|
33
|
+
|
|
34
|
+
## Совместимость
|
|
35
|
+
|
|
36
|
+
Формат состояния не меняется. `GatesAtResult` получает поле `failures`;
|
|
37
|
+
хост, ждавший остановки на первом провале, получает теперь все исполненные
|
|
38
|
+
gates. Новые экспорты: `orderedScope`, `gatePrerequisites`,
|
|
39
|
+
`explicitPrerequisites`, `standaloneScope`. Матрица — [upgrade](../upgrade.md).
|
|
40
|
+
|
|
41
|
+
## Проверка выпуска
|
|
42
|
+
|
|
43
|
+
Затронутые тесты на реальных Git-фикстурах (`gates-at`: профиль в порядке
|
|
44
|
+
массива с установкой первой и без `dependsOn`, петля через неявное ребро,
|
|
45
|
+
пустой `dependsOn`, цепочки двух и трёх уровней, смешанная цепочка, провал
|
|
46
|
+
неявной предпосылки; `runner` T01, T09); каждый новый тест обнаруживает свой
|
|
47
|
+
мутант реализации. Полный `npm run check` перед публикацией выполняет
|
|
48
|
+
ведущий. Живые модели не вызывались.
|