devcontour-harness 0.1.0-alpha.18 → 0.1.0-alpha.19
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 +12 -2
- package/docs/architecture.md +48 -0
- package/docs/contracts.md +3 -0
- package/docs/quickstart.md +1 -1
- package/docs/release-notes/0.1.0-alpha.19.md +96 -0
- package/docs/upgrade.md +17 -16
- package/lib/cli.js +7 -1
- package/lib/contracts/cli.d.ts +30 -2
- package/lib/contracts/events.d.ts +21 -0
- package/lib/contracts/events.js +7 -0
- package/lib/contracts/execution.d.ts +24 -3
- package/lib/contracts/execution.js +14 -2
- package/lib/contracts/planning.js +2 -2
- package/lib/contracts/policy.d.ts +1 -1
- package/lib/contracts/ports.d.ts +6 -0
- package/lib/contracts/primitives.d.ts +13 -0
- package/lib/contracts/primitives.js +15 -0
- package/lib/contracts/profiles.js +2 -2
- package/lib/contracts/published.d.ts +23 -2
- package/lib/contracts/review.d.ts +2 -2
- package/lib/contracts/review.js +2 -2
- package/lib/contracts/work.js +3 -3
- package/lib/control/base-move.js +2 -2
- package/lib/control/harness.d.ts +1 -1
- package/lib/control/harness.js +7 -2
- package/lib/control/workflow.js +6 -0
- package/lib/engine/budget.d.ts +1 -1
- package/lib/engine/engine.d.ts +14 -2
- package/lib/engine/engine.js +40 -1
- package/lib/engine/runner.d.ts +11 -1
- package/lib/engine/runner.js +82 -11
- package/lib/environment/git-trust.d.ts +36 -0
- package/lib/environment/git-trust.js +174 -0
- package/lib/environment/isolation.d.ts +103 -1
- package/lib/environment/isolation.js +340 -5
- package/lib/environment/process.d.ts +5 -0
- package/lib/environment/process.js +20 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +4 -0
- package/lib/integrations/connector/config.js +2 -2
- package/lib/storage/document.d.ts +10 -2
- package/lib/verification/confirm.js +2 -2
- package/lib/verification/gates.d.ts +12 -1
- package/lib/verification/gates.js +81 -8
- package/lib/verification/requirements.js +6 -1
- package/package.json +1 -1
- package/schemas/execution-document.schema.json +27 -5
- package/schemas/plan-draft.schema.json +2 -2
- package/schemas/run-event.schema.json +22 -0
- package/schemas/work-graph.schema.json +2 -2
- package/schemas/work-order.schema.json +2 -2
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.19` — предварительный выпуск (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.19 # точная версия
|
|
32
32
|
# или: npm install --save-exact devcontour-harness@alpha # текущая alpha
|
|
33
33
|
npx harness --version
|
|
34
34
|
```
|
|
@@ -123,6 +123,16 @@ PASS» нет. Адаптеры хоста реализуют порты `Execut
|
|
|
123
123
|
`devcontour-harness/schemas/<имя>.schema.json`. Декларации используют типы
|
|
124
124
|
Node.js: TypeScript-потребителю нужен `@types/node` (или `skipLibCheck`).
|
|
125
125
|
|
|
126
|
+
## Выпуск 0.1.0-alpha.19
|
|
127
|
+
|
|
128
|
+
Провал gate интеграции после зелёного кандидата повторяется один раз
|
|
129
|
+
(`recheck`; контрпример свойства или корпуса — нет); области gates до
|
|
130
|
+
`GATE_SCOPE_LIMIT`; дешевле такты очереди. Песочница: каталоги IDE внутри
|
|
131
|
+
`node_modules` открыты, запреты `.git` явные, git хоста сверяет checkout
|
|
132
|
+
(`hostGitArgs`) и снимает исполняемые настройки, защищённые пути сверяются
|
|
133
|
+
после gate, класс `environment` — только по журналу ядра. Подробно и с
|
|
134
|
+
известными пробелами — [заметки выпуска](docs/release-notes/0.1.0-alpha.19.md).
|
|
135
|
+
|
|
126
136
|
## Выпуск 0.1.0-alpha.18
|
|
127
137
|
|
|
128
138
|
`runGatesAt` исполняет gates с предпосылками профиля: явный `dependsOn` или,
|
package/docs/architecture.md
CHANGED
|
@@ -546,6 +546,16 @@ executable. Live smoke — отдельный opt-in с явно заданны
|
|
|
546
546
|
прежнего владельца, истёкший lease и второй controller ничего не меняют.
|
|
547
547
|
- **Точные SHA.** PASS gate и ревью относится к конкретному candidate или
|
|
548
548
|
integration SHA; доказательство другой фазы или другого SHA не засчитывается.
|
|
549
|
+
- **Повтор провала интеграции.** Если собственный gate поручения прошёл на
|
|
550
|
+
кандидате, но упал на integration, controller один раз на кандидата повторяет
|
|
551
|
+
его на том же integration SHA до того, как засчитать отказ `gate`. Обе записи
|
|
552
|
+
остаются; у повтора `recheck: {of, outcome}` — ссылка на первую запись и
|
|
553
|
+
исход: `flaky` (повтор прошёл, первый провал вызван средой, например бюджетом
|
|
554
|
+
времени под нагрузкой) или `confirmed` (отказ засчитывается как прежде). Лог
|
|
555
|
+
повтора — в `integration/recheck/`; замер — стадия `integration-recheck:<gate>`.
|
|
556
|
+
Провал, в отчёте которого названо проваленное свойство или случай корпуса,
|
|
557
|
+
не повторяется: это найденный контрпример, и удачный второй запуск
|
|
558
|
+
недетерминированной проверки его не отменяет.
|
|
549
559
|
- **Атомарная приёмка.** Продвижение target ref — compare-and-swap внутри
|
|
550
560
|
транзакции приёмки. Чужой коммит в target ref не теряется: попытка начнётся
|
|
551
561
|
от новой базы. Падение между update-ref и записью принятия восстанавливается
|
|
@@ -555,6 +565,44 @@ executable. Live smoke — отдельный opt-in с явно заданны
|
|
|
555
565
|
- **Изоляция.** Режим `os` реально ограничивает процессы writer, reviewer и
|
|
556
566
|
gates; без механизма песочницы команда не запускается — тихого перехода к
|
|
557
567
|
запуску без неё нет. Зависшие процессы останавливаются вместе с потомками.
|
|
568
|
+
Обязательные запреты записи sandbox-runtime (конфигурация shell и git,
|
|
569
|
+
`.git/hooks`, `.mcp.json`, `.claude/commands|agents`, каталоги IDE)
|
|
570
|
+
действуют на весь checkout проверки, а не только на её рабочий каталог.
|
|
571
|
+
Исключение одно: каталоги IDE (`.idea`, `.vscode`) внутри `node_modules`
|
|
572
|
+
открыты — пакеты их публикуют, а IDE дерево зависимостей как конфигурацию
|
|
573
|
+
проекта не открывает. На Linux srt пропускает `node_modules` сам; на macOS
|
|
574
|
+
srt запускается из каталога проверки, а запреты задаются явно: каталоги IDE
|
|
575
|
+
закрыты в корне и в каждом подкаталоге существующих каталогов до глубины 3
|
|
576
|
+
(кроме `node_modules`), прочие имена — на любой глубине. Новый каталог
|
|
577
|
+
глубже существующего уровня этим не закрыт — граница подхода (srt на Linux
|
|
578
|
+
закрывает только уже существующие пути). Файл `.git` рабочего дерева,
|
|
579
|
+
перенаправления обычного `.git` (`commondir`, `gitdir`, `config.worktree`) и
|
|
580
|
+
вложенные `.git` на любой глубине тоже закрыты (на Linux — только
|
|
581
|
+
существующий файл `.git`). Дерево больше предела перечисления — отказ
|
|
582
|
+
проверки классом `environment`, а не молча урезанные запреты.
|
|
583
|
+
- **Сверка защищённых путей.** Запреты песочницы проверяют только путь
|
|
584
|
+
операции: каталог, собранный в `node_modules` и перенесённый в дерево
|
|
585
|
+
проекта, ими не закрыт. До и после каждого gate и вокруг работы исполнителя
|
|
586
|
+
сравнивается снимок защищённых имён вне `node_modules` (каталоги IDE,
|
|
587
|
+
конфигурация shell и git, `.claude`, `.git`); новое или изменённое — класс
|
|
588
|
+
`scope-violation` с путями в сообщении.
|
|
589
|
+
- **Классификация отказов песочницы.** Отказ — класс `environment` только
|
|
590
|
+
тогда, когда журнал ядра macOS подтвердил отказ обязательного запрета внутри
|
|
591
|
+
дерева проверки: команда начинается с уникального токена, и записи srt этой
|
|
592
|
+
проверки отличаются от чужих. Текст вывода свидетельством не служит, запись
|
|
593
|
+
вне дерева — ошибка кода (`gate`). На Linux такого свидетельства нет, и
|
|
594
|
+
отказ остаётся `gate`.
|
|
595
|
+
- **Git хоста над деревом проверки.** Каждый вызов git хоста сначала сверяет,
|
|
596
|
+
куда git придёт: файл `.git` дерева, созданного `worktree add`, не изменён;
|
|
597
|
+
gitdir и общий каталог лежат вне дерева и согласованы; `commondir`/`gitdir`
|
|
598
|
+
в обычном `.git` и вложенный репозиторий внутри известного дерева — отказ
|
|
599
|
+
(`scope-violation` в gate). Поверх — `-c core.fsmonitor=false -c
|
|
600
|
+
core.hooksPath=/dev/null -c protocol.ext.allow=never`: hooks репозитория при
|
|
601
|
+
коммитах harness не исполняются.
|
|
602
|
+
- **Чего ещё нет.** Регрессионных тестов в песочнице для запретов `.git`, для
|
|
603
|
+
сверки после переноса каталога и для отказа по пределу перечисления пока
|
|
604
|
+
нет: эти пути покрыты только тестами SBX01–SBX05 и модульными тестами
|
|
605
|
+
`git-trust`.
|
|
558
606
|
- **Секреты.** Значения секретов маскируются во всём сохраняемом: логах,
|
|
559
607
|
артефактах ревью, evidence, событиях и результате.
|
|
560
608
|
- **Бюджеты.** Проверяются до вызова модели в той же транзакции, что и запись
|
package/docs/contracts.md
CHANGED
|
@@ -615,6 +615,9 @@ manifestDigest, impact?, evidence[], error?}`. Смена любого SHA де
|
|
|
615
615
|
`moveBase`/`fencedRefMove`, `runGate`/`runCheck` (и разбор отчёта
|
|
616
616
|
`junitSummary`, `prepareReportPath`, `sandboxBlockedHosts`), `unprovenReason`,
|
|
617
617
|
`ReviewProbes`, маскирование (`redactor`, `redactDeep`, `redactError`),
|
|
618
|
+
git хоста над checkout с чужим кодом (`hostGitArgs`, `assertTrustedCheckout`,
|
|
619
|
+
`UntrustedCheckoutError`, `gitHardening`, учёт деревьев `rememberWorktree`/
|
|
620
|
+
`forgetWorktree`/`worktreeKey`/`worktreeAddPath`, `resetGitTrust` для тестов),
|
|
618
621
|
корпус (`CorpusStore`, подтверждение случая `submitCase` с `ConfirmContext`),
|
|
619
622
|
ограниченный разбор по свойству (`analyzeRecovery`, `applyCases`,
|
|
620
623
|
`recoveryBrief`; назначение хоста — модель и профиль ведущего — передаётся
|
package/docs/quickstart.md
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# devcontour-harness 0.1.0-alpha.19
|
|
2
|
+
|
|
3
|
+
Меньше трения в цикле исполнения и жёстче граница песочницы: провал
|
|
4
|
+
интеграции, вызванный средой, повторяется один раз, установка зависимостей
|
|
5
|
+
не падает на каталогах IDE внутри `node_modules`, а git хоста не исполняет
|
|
6
|
+
конфигурацию, которую записал чужой код. Включает всё из
|
|
7
|
+
[0.1.0-alpha.18](0.1.0-alpha.18.md). `maxAttempts`, правила находок и
|
|
8
|
+
принятие target ref не менялись.
|
|
9
|
+
|
|
10
|
+
## Что нового
|
|
11
|
+
|
|
12
|
+
### Цикл исполнения
|
|
13
|
+
|
|
14
|
+
- **Ограниченный повтор провала интеграции.** Собственный gate поручения,
|
|
15
|
+
прошедший на кандидате и упавший на integration, повторяется один раз на
|
|
16
|
+
кандидата на том же integration SHA, прежде чем засчитать отказ `gate`.
|
|
17
|
+
Обе записи остаются; у повтора `recheck: {of, outcome}` — ссылка на первую
|
|
18
|
+
запись и исход `flaky` (повтор прошёл) или `confirmed` (провал
|
|
19
|
+
засчитывается как прежде). Лог повтора — в `integration/recheck/`, замер —
|
|
20
|
+
стадия `integration-recheck:<gate>`. Удачный повтор принимает кандидата без
|
|
21
|
+
новой реализации. Кандидат, переиспользованный следующей попыткой, второго
|
|
22
|
+
повтора не получает; движок отклоняет второй повтор в попытке и исход,
|
|
23
|
+
не согласованный с записью.
|
|
24
|
+
- **Контрпример не повторяется.** Провал, в отчёте которого названо
|
|
25
|
+
проваленное свойство или случай корпуса, не повторяется: удачный второй
|
|
26
|
+
запуск недетерминированной проверки не отменяет найденного входа.
|
|
27
|
+
- **Шире области gates.** Область gates задачи, поручения, потребителя и
|
|
28
|
+
основания ревью вмещает до `GATE_SCOPE_LIMIT` (100, предел gates профиля)
|
|
29
|
+
вместо 20; превышение — понятный отказ с величиной и исправлением.
|
|
30
|
+
Константа экспортируется.
|
|
31
|
+
- **Дешевле такты.** `expire()` без истёкших попыток не открывает транзакцию
|
|
32
|
+
записи; такт очереди читает активные попытки через необязательный быстрый
|
|
33
|
+
путь `ExecutionView.activeAttempts`. Завершённое задание workflow сообщает
|
|
34
|
+
израсходованные попытки стадий, а не сброшенный счётчик.
|
|
35
|
+
|
|
36
|
+
### Песочница
|
|
37
|
+
|
|
38
|
+
- **Каталоги IDE внутри `node_modules` открыты.** Пакеты публикуют `.idea/`,
|
|
39
|
+
и установка в чистом дереве падала с EPERM при любом коде. На macOS srt
|
|
40
|
+
запускается из служебного каталога проверки, а обязательные запреты
|
|
41
|
+
задаются явно на весь checkout: конфигурация shell, git, MCP и Claude,
|
|
42
|
+
`.git/hooks`, `.git/config` — на любой глубине; `.idea`/`.vscode` — в
|
|
43
|
+
корне и в каждом существующем подкаталоге до глубины 3, кроме
|
|
44
|
+
`node_modules`. Linux не меняется (srt пропускает `node_modules` сам).
|
|
45
|
+
- **Явные запреты `.git`.** На macOS закрыты файл `.git` рабочего дерева,
|
|
46
|
+
перенаправления обычного `.git` (`commondir`, `gitdir`, `config.worktree`)
|
|
47
|
+
и вложенные `.git` на любой глубине; на Linux — существующий файл `.git`.
|
|
48
|
+
Дерево больше предела перечисления — отказ класса `environment`, а не
|
|
49
|
+
молча урезанные запреты.
|
|
50
|
+
- **Git хоста над деревом проверки (`git-trust`).** Каждый вызов git хоста
|
|
51
|
+
сначала сверяет, куда git придёт: файл `.git` дерева, созданного
|
|
52
|
+
`worktree add`, не изменён; gitdir и общий каталог лежат вне дерева и
|
|
53
|
+
согласованы. Перенаправленный `gitdir`/`commondir` в обычном `.git` и
|
|
54
|
+
вложенный репозиторий внутри известного дерева — отказ
|
|
55
|
+
(`UntrustedCheckoutError`, в gate — `scope-violation`). Поверх —
|
|
56
|
+
`-c core.fsmonitor=false -c core.hooksPath=/dev/null -c protocol.ext.allow=never`:
|
|
57
|
+
hooks репозитория при коммитах harness не исполняются. Экспорт для хоста:
|
|
58
|
+
`hostGitArgs`, `assertTrustedCheckout`, `UntrustedCheckoutError`,
|
|
59
|
+
`gitHardening`, `rememberWorktree`, `forgetWorktree`, `worktreeKey`,
|
|
60
|
+
`worktreeAddPath`, `resetGitTrust` (для тестов).
|
|
61
|
+
- **Сверка защищённых путей после gate.** Запреты песочницы видят только
|
|
62
|
+
путь операции, и каталог, собранный в `node_modules` и перенесённый в
|
|
63
|
+
дерево проекта, ими не закрыт. Вокруг каждого gate и работы исполнителя
|
|
64
|
+
сравнивается снимок защищённых имён вне `node_modules`; новое или
|
|
65
|
+
изменённое — `scope-violation` с путями в сообщении.
|
|
66
|
+
- **Класс `environment` — только по журналу ядра.** Отказ песочницы
|
|
67
|
+
классифицируется как сбой среды, только когда журнал ядра macOS подтвердил
|
|
68
|
+
отказ обязательного запрета внутри дерева проверки (команда проверки
|
|
69
|
+
помечена уникальным токеном). Текст вывода (EPERM) свидетельством не
|
|
70
|
+
служит; запись вне дерева и любой отказ на Linux остаются `gate`.
|
|
71
|
+
|
|
72
|
+
## Известные пробелы
|
|
73
|
+
|
|
74
|
+
- Регрессионные тесты в настоящей песочнице для запретов `.git`, для сверки
|
|
75
|
+
защищённых путей после переноса каталога и для отказа по пределу
|
|
76
|
+
перечисления не написаны (решение владельца проекта). Эти пути покрыты
|
|
77
|
+
тестами SBX01–SBX05 и модульными тестами `git-trust`.
|
|
78
|
+
- Запреты на Linux и запуск/остановка наблюдения за журналом ядра тестами не
|
|
79
|
+
покрыты.
|
|
80
|
+
- Поэтому два мутанта этих путей (D1, D2) выживают.
|
|
81
|
+
|
|
82
|
+
## Совместимость
|
|
83
|
+
|
|
84
|
+
Формат состояния: новое необязательное поле `recheck` у evidence gate и в
|
|
85
|
+
событии `attempt.gate`, области gates длиннее 20. Прежние версии
|
|
86
|
+
отклоняют такое состояние строгой схемой → откат через копию. Хост, у
|
|
87
|
+
которого хуки gate или writer меняют защищённые имена, получит
|
|
88
|
+
`scope-violation`. Матрица — [upgrade](../upgrade.md).
|
|
89
|
+
|
|
90
|
+
## Проверка выпуска
|
|
91
|
+
|
|
92
|
+
Затронутые тесты (`runner`, `engine`, `repair`, `planning-schema`,
|
|
93
|
+
`cli-h3-contract`, `probe-gates`, `review-inspection-runner`, `git-trust`,
|
|
94
|
+
`sandbox-install`, `boundaries`), lint, typecheck и `schemas:check`. Полный
|
|
95
|
+
`npm run check` перед публикацией выполняет ведущий. Живые модели не
|
|
96
|
+
вызывались.
|
package/docs/upgrade.md
CHANGED
|
@@ -21,22 +21,23 @@
|
|
|
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 | Читает 0.1.0-alpha.14 | Читает 0.1.0-alpha.15 | Читает 0.1.0-alpha.16 | Читает 0.1.0-alpha.17
|
|
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
|
-
| alpha.14 с договором проверки `reference` или `gates` обязательства | не проверялось | не проверялось | не проверялось | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | да | да | да | да
|
|
36
|
-
| alpha.17 с `interrupted`, `inputClasses`, `classified`, `neutralFailures`, `alreadySatisfied` в evidence ревью или классом отказа `unfinished`/`needs-lead` | не проверялось | не проверялось | не проверялось | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | да
|
|
37
|
-
|
|
|
38
|
-
|
|
39
|
-
|
|
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 | Читает 0.1.0-alpha.17 | Читает 0.1.0-alpha.18 | Читает 0.1.0-alpha.19 | Пишет поверх | Примечание |
|
|
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
|
+
| alpha.17 с `interrupted`, `inputClasses`, `classified`, `neutralFailures`, `alreadySatisfied` в evidence ревью или классом отказа `unfinished`/`needs-lead` | не проверялось | не проверялось | не проверялось | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | да | да | да | — | попытка (`interrupted`, `inputClasses`, `classified`), поручение (`neutralFailures`), `alreadySatisfied` evidence ревью и классы отказа `unfinished`, `needs-lead` — новые значения строгих схем; прежние версии их отклоняют → откат через копию |
|
|
37
|
+
| alpha.19 с `recheck` в evidence gate или областью gates длиннее 20 | не проверялось | не проверялось | не проверялось | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | **нет** (строгая схема) | да | — | evidence gate и событие `attempt.gate` (`recheck`), области gates поручения, задачи, потребителя и `alreadySatisfied` до 100 — новые значения строгих схем; прежние версии их отклоняют → откат через копию |
|
|
38
|
+
| неизвестная `stateVersion` | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет, отказ до записи | нет | `STATE_VERSION_UNSUPPORTED`, exit 4 |
|
|
39
|
+
|
|
40
|
+
Столбец 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). alpha.17 читает всё, что читает alpha.16, и добавляет необязательные поля попытки, поручения и evidence ревью и классы отказа `unfinished` и `needs-lead` (строка alpha.17); alpha.18 формат состояния не меняет и читает всё, что читает alpha.17. alpha.19 читает всё, что читает alpha.18, и добавляет необязательное поле `recheck` evidence gate и области gates до 100 (строка alpha.19). Каждая следующая версия добавляет сюда свой столбец. Отказ неизвестного
|
|
40
41
|
формата до записи проверяют тесты совместимости пакета
|
|
41
42
|
<!-- repo-only -->(`tests/compatibility.test.ts`)<!-- /repo-only -->.
|
|
42
43
|
|
package/lib/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ import { planCheck, planRequestOf } from "./planning/check.js";
|
|
|
18
18
|
import { checkJsonBytes } from "./catalog/bytes.js";
|
|
19
19
|
import { isSharedOperation, sharedOperations } from "./catalog/shared.js";
|
|
20
20
|
import { harnessCapabilities } from "./catalog/harness.js";
|
|
21
|
+
import { hostGitArgs } from "./environment/process.js";
|
|
21
22
|
import { FileContextSource, FileResultSink, FileWorkSource } from "./connectors/files.js";
|
|
22
23
|
const usage = `harness ${HARNESS_VERSION}
|
|
23
24
|
|
|
@@ -124,7 +125,12 @@ const reachableIn = (b, repositoryId, sha) => {
|
|
|
124
125
|
if (!repo)
|
|
125
126
|
return false;
|
|
126
127
|
try {
|
|
127
|
-
execFileSync('git',
|
|
128
|
+
execFileSync('git', hostGitArgs(resolve(b.baseDir, repo.path), [
|
|
129
|
+
'merge-base',
|
|
130
|
+
'--is-ancestor',
|
|
131
|
+
sha,
|
|
132
|
+
repo.targetRef,
|
|
133
|
+
]), {
|
|
128
134
|
cwd: resolve(b.baseDir, repo.path),
|
|
129
135
|
stdio: 'ignore',
|
|
130
136
|
});
|
package/lib/contracts/cli.d.ts
CHANGED
|
@@ -598,8 +598,8 @@ export declare const statusDataSchema: z.ZodObject<{
|
|
|
598
598
|
}, z.core.$strict>>;
|
|
599
599
|
budgets: z.ZodOptional<z.ZodObject<{
|
|
600
600
|
onUnknown: z.ZodEnum<{
|
|
601
|
-
stop: "stop";
|
|
602
601
|
continue: "continue";
|
|
602
|
+
stop: "stop";
|
|
603
603
|
}>;
|
|
604
604
|
budgets: z.ZodArray<z.ZodObject<{
|
|
605
605
|
scope: z.ZodObject<{
|
|
@@ -710,6 +710,13 @@ export declare const eventsDataSchema: z.ZodObject<{
|
|
|
710
710
|
passed: z.ZodBoolean;
|
|
711
711
|
evidenceId: z.ZodString;
|
|
712
712
|
consumer: z.ZodOptional<z.ZodString>;
|
|
713
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
714
|
+
of: z.ZodString;
|
|
715
|
+
outcome: z.ZodEnum<{
|
|
716
|
+
flaky: "flaky";
|
|
717
|
+
confirmed: "confirmed";
|
|
718
|
+
}>;
|
|
719
|
+
}, z.core.$strict>>;
|
|
713
720
|
}, z.core.$strict> | z.ZodObject<{
|
|
714
721
|
phase: z.ZodEnum<{
|
|
715
722
|
candidate: "candidate";
|
|
@@ -965,6 +972,13 @@ export declare const eventsDataSchema: z.ZodObject<{
|
|
|
965
972
|
passed: z.ZodBoolean;
|
|
966
973
|
evidenceId: z.ZodString;
|
|
967
974
|
consumer: z.ZodOptional<z.ZodString>;
|
|
975
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
976
|
+
of: z.ZodString;
|
|
977
|
+
outcome: z.ZodEnum<{
|
|
978
|
+
flaky: "flaky";
|
|
979
|
+
confirmed: "confirmed";
|
|
980
|
+
}>;
|
|
981
|
+
}, z.core.$strict>>;
|
|
968
982
|
}, z.core.$strict> | z.ZodObject<{
|
|
969
983
|
phase: z.ZodEnum<{
|
|
970
984
|
candidate: "candidate";
|
|
@@ -2273,8 +2287,8 @@ export declare const cliDataSchemas: {
|
|
|
2273
2287
|
}, z.core.$strict>>;
|
|
2274
2288
|
budgets: z.ZodOptional<z.ZodObject<{
|
|
2275
2289
|
onUnknown: z.ZodEnum<{
|
|
2276
|
-
stop: "stop";
|
|
2277
2290
|
continue: "continue";
|
|
2291
|
+
stop: "stop";
|
|
2278
2292
|
}>;
|
|
2279
2293
|
budgets: z.ZodArray<z.ZodObject<{
|
|
2280
2294
|
scope: z.ZodObject<{
|
|
@@ -2385,6 +2399,13 @@ export declare const cliDataSchemas: {
|
|
|
2385
2399
|
passed: z.ZodBoolean;
|
|
2386
2400
|
evidenceId: z.ZodString;
|
|
2387
2401
|
consumer: z.ZodOptional<z.ZodString>;
|
|
2402
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
2403
|
+
of: z.ZodString;
|
|
2404
|
+
outcome: z.ZodEnum<{
|
|
2405
|
+
flaky: "flaky";
|
|
2406
|
+
confirmed: "confirmed";
|
|
2407
|
+
}>;
|
|
2408
|
+
}, z.core.$strict>>;
|
|
2388
2409
|
}, z.core.$strict> | z.ZodObject<{
|
|
2389
2410
|
phase: z.ZodEnum<{
|
|
2390
2411
|
candidate: "candidate";
|
|
@@ -2640,6 +2661,13 @@ export declare const cliDataSchemas: {
|
|
|
2640
2661
|
passed: z.ZodBoolean;
|
|
2641
2662
|
evidenceId: z.ZodString;
|
|
2642
2663
|
consumer: z.ZodOptional<z.ZodString>;
|
|
2664
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
2665
|
+
of: z.ZodString;
|
|
2666
|
+
outcome: z.ZodEnum<{
|
|
2667
|
+
flaky: "flaky";
|
|
2668
|
+
confirmed: "confirmed";
|
|
2669
|
+
}>;
|
|
2670
|
+
}, z.core.$strict>>;
|
|
2643
2671
|
}, z.core.$strict> | z.ZodObject<{
|
|
2644
2672
|
phase: z.ZodEnum<{
|
|
2645
2673
|
candidate: "candidate";
|
|
@@ -79,6 +79,13 @@ export declare const eventPayloads: {
|
|
|
79
79
|
passed: z.ZodBoolean;
|
|
80
80
|
evidenceId: z.ZodString;
|
|
81
81
|
consumer: z.ZodOptional<z.ZodString>;
|
|
82
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
83
|
+
of: z.ZodString;
|
|
84
|
+
outcome: z.ZodEnum<{
|
|
85
|
+
flaky: "flaky";
|
|
86
|
+
confirmed: "confirmed";
|
|
87
|
+
}>;
|
|
88
|
+
}, z.core.$strict>>;
|
|
82
89
|
}, z.core.$strict>;
|
|
83
90
|
readonly 'attempt.review': z.ZodObject<{
|
|
84
91
|
phase: z.ZodEnum<{
|
|
@@ -381,6 +388,13 @@ export declare const runEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
381
388
|
passed: z.ZodBoolean;
|
|
382
389
|
evidenceId: z.ZodString;
|
|
383
390
|
consumer: z.ZodOptional<z.ZodString>;
|
|
391
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
392
|
+
of: z.ZodString;
|
|
393
|
+
outcome: z.ZodEnum<{
|
|
394
|
+
flaky: "flaky";
|
|
395
|
+
confirmed: "confirmed";
|
|
396
|
+
}>;
|
|
397
|
+
}, z.core.$strict>>;
|
|
384
398
|
}, z.core.$strict> | z.ZodObject<{
|
|
385
399
|
phase: z.ZodEnum<{
|
|
386
400
|
candidate: "candidate";
|
|
@@ -636,6 +650,13 @@ export declare const runEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
636
650
|
passed: z.ZodBoolean;
|
|
637
651
|
evidenceId: z.ZodString;
|
|
638
652
|
consumer: z.ZodOptional<z.ZodString>;
|
|
653
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
654
|
+
of: z.ZodString;
|
|
655
|
+
outcome: z.ZodEnum<{
|
|
656
|
+
flaky: "flaky";
|
|
657
|
+
confirmed: "confirmed";
|
|
658
|
+
}>;
|
|
659
|
+
}, z.core.$strict>>;
|
|
639
660
|
}, z.core.$strict> | z.ZodObject<{
|
|
640
661
|
phase: z.ZodEnum<{
|
|
641
662
|
candidate: "candidate";
|
package/lib/contracts/events.js
CHANGED
|
@@ -54,6 +54,13 @@ export const eventPayloads = {
|
|
|
54
54
|
passed: z.boolean(),
|
|
55
55
|
evidenceId: z.string().min(1).max(200),
|
|
56
56
|
consumer: idSchema.optional(),
|
|
57
|
+
/** Повтор провала интеграции: повторённая запись и исход. */
|
|
58
|
+
recheck: z
|
|
59
|
+
.strictObject({
|
|
60
|
+
of: z.string().min(1).max(200),
|
|
61
|
+
outcome: z.enum(['flaky', 'confirmed']),
|
|
62
|
+
})
|
|
63
|
+
.optional(),
|
|
57
64
|
}),
|
|
58
65
|
'attempt.review': z.strictObject({
|
|
59
66
|
phase,
|
|
@@ -276,6 +276,13 @@ export declare const evidenceRecordSchema: z.ZodObject<{
|
|
|
276
276
|
digest: z.ZodString;
|
|
277
277
|
summary: z.ZodString;
|
|
278
278
|
consumer: z.ZodOptional<z.ZodString>;
|
|
279
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
280
|
+
of: z.ZodString;
|
|
281
|
+
outcome: z.ZodEnum<{
|
|
282
|
+
flaky: "flaky";
|
|
283
|
+
confirmed: "confirmed";
|
|
284
|
+
}>;
|
|
285
|
+
}, z.core.$strict>>;
|
|
279
286
|
inspection: z.ZodOptional<z.ZodObject<{
|
|
280
287
|
mode: z.ZodEnum<{
|
|
281
288
|
commands: "commands";
|
|
@@ -367,9 +374,9 @@ export declare const evidenceRecordSchema: z.ZodObject<{
|
|
|
367
374
|
issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
368
375
|
path: z.ZodString;
|
|
369
376
|
reason: z.ZodEnum<{
|
|
377
|
+
schema: "schema";
|
|
370
378
|
unknown: "unknown";
|
|
371
379
|
missing: "missing";
|
|
372
|
-
schema: "schema";
|
|
373
380
|
duplicate: "duplicate";
|
|
374
381
|
"not-open": "not-open";
|
|
375
382
|
"approved-with-blocking": "approved-with-blocking";
|
|
@@ -837,6 +844,13 @@ export declare const attemptStateSchema: z.ZodObject<{
|
|
|
837
844
|
digest: z.ZodString;
|
|
838
845
|
summary: z.ZodString;
|
|
839
846
|
consumer: z.ZodOptional<z.ZodString>;
|
|
847
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
848
|
+
of: z.ZodString;
|
|
849
|
+
outcome: z.ZodEnum<{
|
|
850
|
+
flaky: "flaky";
|
|
851
|
+
confirmed: "confirmed";
|
|
852
|
+
}>;
|
|
853
|
+
}, z.core.$strict>>;
|
|
840
854
|
inspection: z.ZodOptional<z.ZodObject<{
|
|
841
855
|
mode: z.ZodEnum<{
|
|
842
856
|
commands: "commands";
|
|
@@ -928,9 +942,9 @@ export declare const attemptStateSchema: z.ZodObject<{
|
|
|
928
942
|
issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
929
943
|
path: z.ZodString;
|
|
930
944
|
reason: z.ZodEnum<{
|
|
945
|
+
schema: "schema";
|
|
931
946
|
unknown: "unknown";
|
|
932
947
|
missing: "missing";
|
|
933
|
-
schema: "schema";
|
|
934
948
|
duplicate: "duplicate";
|
|
935
949
|
"not-open": "not-open";
|
|
936
950
|
"approved-with-blocking": "approved-with-blocking";
|
|
@@ -3131,6 +3145,13 @@ export declare const executionDocumentSchema: z.ZodObject<{
|
|
|
3131
3145
|
digest: z.ZodString;
|
|
3132
3146
|
summary: z.ZodString;
|
|
3133
3147
|
consumer: z.ZodOptional<z.ZodString>;
|
|
3148
|
+
recheck: z.ZodOptional<z.ZodObject<{
|
|
3149
|
+
of: z.ZodString;
|
|
3150
|
+
outcome: z.ZodEnum<{
|
|
3151
|
+
flaky: "flaky";
|
|
3152
|
+
confirmed: "confirmed";
|
|
3153
|
+
}>;
|
|
3154
|
+
}, z.core.$strict>>;
|
|
3134
3155
|
inspection: z.ZodOptional<z.ZodObject<{
|
|
3135
3156
|
mode: z.ZodEnum<{
|
|
3136
3157
|
commands: "commands";
|
|
@@ -3222,9 +3243,9 @@ export declare const executionDocumentSchema: z.ZodObject<{
|
|
|
3222
3243
|
issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3223
3244
|
path: z.ZodString;
|
|
3224
3245
|
reason: z.ZodEnum<{
|
|
3246
|
+
schema: "schema";
|
|
3225
3247
|
unknown: "unknown";
|
|
3226
3248
|
missing: "missing";
|
|
3227
|
-
schema: "schema";
|
|
3228
3249
|
duplicate: "duplicate";
|
|
3229
3250
|
"not-open": "not-open";
|
|
3230
3251
|
"approved-with-blocking": "approved-with-blocking";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { STATE_VERSION } from "./version.js";
|
|
3
|
-
import { digestSchema, gitShaSchema, idSchema, isoTimeSchema, relativePathSchema, runtimeNameSchema, trimmedText, } from "./primitives.js";
|
|
3
|
+
import { digestSchema, gitShaSchema, idSchema, isoTimeSchema, relativePathSchema, runtimeNameSchema, trimmedText, gateScopeSchema, } from "./primitives.js";
|
|
4
4
|
import { workGraphSchema, workOrderSchema } from "./work.js";
|
|
5
5
|
import { contextPinSchema, contextSnapshotSchema } from "./context.js";
|
|
6
6
|
import { deliveryStateSchema, jointActiveSchema, jointFailedSchema, jointPassedSchema, } from "./result.js";
|
|
@@ -241,6 +241,17 @@ export const evidenceRecordSchema = z.strictObject({
|
|
|
241
241
|
summary: z.string(),
|
|
242
242
|
/** Проверка потребителя: компонент, в дереве которого она выполнена. */
|
|
243
243
|
consumer: idSchema.optional(),
|
|
244
|
+
/**
|
|
245
|
+
* Повтор провала gate интеграции на том же SHA: `of` — ID повторённой
|
|
246
|
+
* записи; `flaky` — повтор прошёл (первый провал вызван средой), `confirmed`
|
|
247
|
+
* — провал подтвердился.
|
|
248
|
+
*/
|
|
249
|
+
recheck: z
|
|
250
|
+
.strictObject({
|
|
251
|
+
of: z.string().min(1).max(200),
|
|
252
|
+
outcome: z.enum(['flaky', 'confirmed']),
|
|
253
|
+
})
|
|
254
|
+
.optional(),
|
|
244
255
|
inspection: reviewInspectionSchema.optional(),
|
|
245
256
|
findings: z.array(evidenceFindingSchema).optional(),
|
|
246
257
|
/** Раунд ревью кода: область истории, вызов, протокол, переходы (docs/review-protocol.md). */
|
|
@@ -262,7 +273,7 @@ export const evidenceRecordSchema = z.strictObject({
|
|
|
262
273
|
*/
|
|
263
274
|
alreadySatisfied: z
|
|
264
275
|
.strictObject({
|
|
265
|
-
gates:
|
|
276
|
+
gates: gateScopeSchema(z.string().min(1).max(200)).min(1),
|
|
266
277
|
evidence: z.string().min(1).max(4000),
|
|
267
278
|
/** Механическое основание, найденное controller (`alreadySatisfiedVerdict`). */
|
|
268
279
|
basis: z
|
|
@@ -875,6 +886,7 @@ export const workflowJobSchema = z.strictObject({
|
|
|
875
886
|
owner: z.string().optional(),
|
|
876
887
|
inputDigest: digestSchema,
|
|
877
888
|
stage: z.number().int().min(0),
|
|
889
|
+
/** Попытки текущей стадии; у завершённого задания — все израсходованные попытки стадий. */
|
|
878
890
|
attempts: z.number().int().min(0),
|
|
879
891
|
status: z.enum(['queued', 'running', 'failed', 'stale', 'completed']),
|
|
880
892
|
repairs: z.number().int().min(0).optional(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { errorCodes, HarnessError } from "./errors.js";
|
|
3
|
-
import { digestSchema, gateRefSchema, idSchema, relativePathPattern, roleIdSchema, } from "./primitives.js";
|
|
3
|
+
import { digestSchema, gateRefSchema, idSchema, relativePathPattern, roleIdSchema, gateScopeSchema, } from "./primitives.js";
|
|
4
4
|
import { consumerSchema, propertyIdSchema, workGraphSchema } from "./work.js";
|
|
5
5
|
/**
|
|
6
6
|
* Draft плана: то, что ведущий агент (или хост) предлагает до проверки и
|
|
@@ -35,7 +35,7 @@ export const planDraftTaskShape = {
|
|
|
35
35
|
relatedRepositories: z.array(idSchema).optional(),
|
|
36
36
|
contextPacks: z.array(idSchema).max(30).optional(),
|
|
37
37
|
writePaths: z.array(draftPathSchema).min(1).max(100).optional(),
|
|
38
|
-
gates:
|
|
38
|
+
gates: gateScopeSchema(gateRefSchema).optional(),
|
|
39
39
|
properties: z.array(propertyIdSchema).max(30).optional(),
|
|
40
40
|
resources: z.array(idSchema).max(20).optional(),
|
|
41
41
|
repositoryId: z.string().default('main'),
|
|
@@ -986,8 +986,8 @@ export declare const executionPolicySchema: z.ZodObject<{
|
|
|
986
986
|
timeMs: z.ZodNumber;
|
|
987
987
|
}, z.core.$strict>]>>;
|
|
988
988
|
onUnknown: z.ZodDefault<z.ZodEnum<{
|
|
989
|
-
stop: "stop";
|
|
990
989
|
continue: "continue";
|
|
990
|
+
stop: "stop";
|
|
991
991
|
}>>;
|
|
992
992
|
}, z.core.$strict>>;
|
|
993
993
|
prices: z.ZodDefault<z.ZodArray<z.ZodObject<{
|