@spec-box/sdd 0.9.0 → 0.11.0

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.
Files changed (88) hide show
  1. package/README.md +75 -4
  2. package/assets/adapters/openspec/instructions.md +2 -2
  3. package/assets/adapters/spec-box/instructions.md +1 -1
  4. package/assets/hosts/claude/agent.md +1 -1
  5. package/assets/hosts/claude/project.md +3 -0
  6. package/assets/hosts/codex/AGENTS.md +7 -0
  7. package/assets/hosts/codex/agent.md +10 -0
  8. package/assets/hosts/codex/headless-result.md +2 -0
  9. package/assets/project/overview.md +1 -1
  10. package/assets/prompts/fill-project-docs.md +1 -1
  11. package/assets/roles/challenger.md +9 -2
  12. package/assets/roles/planner.md +4 -2
  13. package/assets/roles/researcher.md +2 -2
  14. package/assets/roles/reviewer.md +2 -0
  15. package/assets/roles/tester.md +2 -0
  16. package/assets/schema/default.yaml +2 -2
  17. package/assets/schema/sbox-answer.schema.json +2 -2
  18. package/assets/skills/sbox-contract.md +23 -0
  19. package/assets/skills/sbox-run.md +34 -14
  20. package/bin/sbox-contract.js +5 -0
  21. package/dist/adapters/host/claude/index.js +13 -19
  22. package/dist/adapters/host/claude/index.js.map +1 -1
  23. package/dist/adapters/host/codex/index.js +61 -0
  24. package/dist/adapters/host/codex/index.js.map +1 -0
  25. package/dist/adapters/host/index.js +9 -2
  26. package/dist/adapters/host/index.js.map +1 -1
  27. package/dist/adapters/runner/codex.js +31 -7
  28. package/dist/adapters/runner/codex.js.map +1 -1
  29. package/dist/adapters/spec/openspec/index.js +15 -1
  30. package/dist/adapters/spec/openspec/index.js.map +1 -1
  31. package/dist/adapters/spec/openspec/parser.js +1 -1
  32. package/dist/adapters/spec/openspec/parser.js.map +1 -1
  33. package/dist/adapters/spec/spec-box/delta.js +1 -1
  34. package/dist/adapters/spec/spec-box/delta.js.map +1 -1
  35. package/dist/adapters/spec/spec-box/index.js +13 -1
  36. package/dist/adapters/spec/spec-box/index.js.map +1 -1
  37. package/dist/adapters/spec/spec-box/yaml.js +1 -1
  38. package/dist/adapters/spec/spec-box/yaml.js.map +1 -1
  39. package/dist/cli/commands/archive.js +28 -0
  40. package/dist/cli/commands/archive.js.map +1 -0
  41. package/dist/cli/commands/host.js +3 -4
  42. package/dist/cli/commands/host.js.map +1 -1
  43. package/dist/cli/commands/models.js +25 -0
  44. package/dist/cli/commands/models.js.map +1 -0
  45. package/dist/cli/commands/protocol.js +4 -2
  46. package/dist/cli/commands/protocol.js.map +1 -1
  47. package/dist/cli/context.js +1 -1
  48. package/dist/cli/context.js.map +1 -1
  49. package/dist/cli/main.js +4 -2
  50. package/dist/cli/main.js.map +1 -1
  51. package/dist/{core/spec-adapter.js → contract/adapter.js} +1 -1
  52. package/dist/contract/adapter.js.map +1 -0
  53. package/dist/contract/cli.js +95 -0
  54. package/dist/contract/cli.js.map +1 -0
  55. package/dist/contract/config.js +13 -0
  56. package/dist/contract/config.js.map +1 -0
  57. package/dist/contract/context.js +60 -0
  58. package/dist/contract/context.js.map +1 -0
  59. package/dist/{core/spec-model.js → contract/model.js} +1 -1
  60. package/dist/contract/model.js.map +1 -0
  61. package/dist/contract/service.js +115 -0
  62. package/dist/contract/service.js.map +1 -0
  63. package/dist/core/archive.js +15 -42
  64. package/dist/core/archive.js.map +1 -1
  65. package/dist/core/change.js +5 -3
  66. package/dist/core/change.js.map +1 -1
  67. package/dist/core/config.js +10 -17
  68. package/dist/core/config.js.map +1 -1
  69. package/dist/core/model-policy.js +54 -0
  70. package/dist/core/model-policy.js.map +1 -0
  71. package/dist/core/packet.js +11 -5
  72. package/dist/core/packet.js.map +1 -1
  73. package/dist/core/phases.js +14 -3
  74. package/dist/core/phases.js.map +1 -1
  75. package/dist/core/report.js +23 -5
  76. package/dist/core/report.js.map +1 -1
  77. package/dist/core/result.js +2 -3
  78. package/dist/core/result.js.map +1 -1
  79. package/dist/core/run.js +11 -8
  80. package/dist/core/run.js.map +1 -1
  81. package/dist/core/runner.js +0 -23
  82. package/dist/core/runner.js.map +1 -1
  83. package/docs/design.md +69 -14
  84. package/package.json +3 -2
  85. package/dist/cli/commands/spec.js +0 -84
  86. package/dist/cli/commands/spec.js.map +0 -1
  87. package/dist/core/spec-adapter.js.map +0 -1
  88. package/dist/core/spec-model.js.map +0 -1
package/docs/design.md CHANGED
@@ -97,7 +97,8 @@
97
97
  | intake | CLI | Папка `changes/<id>/`, `change.yaml`, `request.md` с исходным описанием; при создании из брифа сюда же копируются дельты и решения | Всегда |
98
98
  | research | Роль researcher | `evidence/research.md`: факты о текущем поведении, границы, затронутые спецификации и код, пробелы; первый раздел «Разбор запроса» повторяет явные утверждения запроса дословными цитатами со статусом `подтверждено`, `противоречит` или `не проверено`, CLI сверяет цитаты с текстом запроса. При создании из брифа проверяет, что бриф не устарел | Пробелов, меняющих решение, нет |
99
99
  | propose | Роль planner | `proposal.md` с разделом «Расхождения с запросом» (решение по каждому отступлению от запроса или evidence), размер изменения, сложность реализации и ревью. При создании из брифа берётся из него | Гейт `proposal`, если включён |
100
- | plan | Роль planner, для `large` роль challenger | Дельты `specs/` (при создании из брифа проверяются, а не пишутся), `design.md` с решениями и вопросами, `tasks.md`, `evidence/challenge.md` | `sbox validate` без ошибок, нет вопросов P0, гейт `plan`, если включён |
100
+ | plan | Роль planner | Дельты `specs/` (при создании из брифа проверяются, а не пишутся), `design.md` с решениями и вопросами, `tasks.md` | `sbox validate` без ошибок, нет вопросов P0, гейт `plan`, если включён |
101
+ | challenge | Роль challenger | `evidence/challenge-N.md` (сохраняет CLI) | findings присутствует, нет blocking; иначе возврат в plan |
101
102
  | cover | Роль tester, затем роль reviewer в режиме ревью тестов | Автотесты по сценариям, `coverage.yaml`, `test-plan.md` при необходимости; тесты прошли ИИ-ревью с автоисправлением, запущены и падают по ожидаемой причине | Гейт `tests`, если включён |
102
103
  | implement | Роль implementer, затем CLI | Код, отмеченные задачи в `tasks.md`, узкие проверки; CLI запечатывает change-set: список изменённых путей и дайджест дифа в `changeset.json` | Все задачи отмечены, все тесты из `coverage.yaml` зелёные, защищённые файлы не тронуты |
103
104
  | verify | CLI и роль verifier | `evidence/verify-N.md`: отчёты тестов, покрытие сценариев, соответствие дизайну и правилам, проверки проекта, дымовой запуск по `testing.md`; каждый пункт со статусом PASS, FAIL, PARTIAL или NOT_RUN и список пробелов (manual/CI gaps). если в `design.md` объявлен образец, CLI передаёт верификатору кандидатов подключения нового модуля (`sbox wiring`), а нерассмотренные добавляет в отчёт пунктами PARTIAL для ревьюера | Нет пунктов FAIL, дайджест change-set не изменился |
@@ -114,7 +115,7 @@
114
115
  |---|---|---|
115
116
  | `small` | Поведение продукта не меняется: рефакторинг, инфраструктура, документация | `proposal.md`, `tasks.md`; в `change.yaml` стоит `skip_specs: true`; фаза cover ограничена регрессионными тестами |
116
117
  | `normal` | Меняется поведение в пределах одной-двух capability | `proposal.md`, дельты `specs/`, `design.md`, `tasks.md`, тесты |
117
- | `large` | Несколько capability, новые контракты, миграции, безопасность | Все артефакты плюс аудит плана ролью challenger |
118
+ | `large` | Несколько capability, новые контракты, миграции, безопасность | Все артефакты; аудит плана обязателен при любом размере |
118
119
 
119
120
  ### Гейты, профили и каналы
120
121
 
@@ -126,6 +127,10 @@
126
127
  | `checkpoint` | Нет | Да | Нет | Да |
127
128
  | `autonomous` | Нет | Нет | Нет | Да |
128
129
 
130
+ Фаза challenge следует после гейта plan, учитывает ответы человека и обязательна для всех размеров и уровней автономности. Challenger не меняет артефакты, CLI сохраняет каждый отчёт отдельно. Даже при статусе «готово» blocking findings возвращают в plan; отсутствие findings отклоняет отчёт. Возврат в plan сбрасывает прежние утверждения plan и tests (состояние skipped с reason: plan_changed), сохраняя ответы человека, и требует повторных гейтов, если они включены. Это не отклонение тестов человеком, поэтому tests_review не пропускается при testing.reviewReworks=false. Общий лимит возвратов ограничивает повторные аудиты.
131
+
132
+ При обновлении существующие изменения сохраняют текущую фазу: ожидающий гейт plan после утверждения ведёт в challenge; уже прошедшие планирование не перематываются. Любой последующий возврат в plan включает аудит.
133
+
129
134
  Гейт `plan` стоит до фазы cover: человек смотрит дизайн и спецификации раньше, чем тестировщик потратит запуск на отклонённый дизайн. ИИ-ревью тестов с автоисправлением выполняется при любом профиле. Для пилотов начинаем с `supervised`. Изменение, созданное из брифа дискавери, по умолчанию получает профиль `autonomous`, потому что спецификации и решения уже прошли ревью человека на дискавери.
130
135
 
131
136
  Независимо от профиля инструмент останавливается на вопросе приоритета P0: без ответа нельзя писать спецификации и тесты. Вопросы P1 останавливают только на включённом гейте `plan`, иначе принимается рекомендованный вариант и записывается как допущение. Вопросы P2 не останавливают никогда.
@@ -156,7 +161,7 @@
156
161
 
157
162
  | Категория блокера | Кто выставил | Куда возвращается |
158
163
  |---|---|---|
159
- | `артефакт <id>` | tester, implementer, reviewer, verifier | В фазу plan к планировщику. Если изменились дельты, фаза cover повторяется |
164
+ | `артефакт <id>` | challenger, tester, implementer, reviewer, verifier | В фазу plan к планировщику. Если изменились дельты, фаза cover повторяется |
160
165
  | `тесты` | implementer, reviewer, verifier | В фазу cover к тестировщику |
161
166
  | `реализация` | verifier, reviewer | В фазу implement к реализатору с текстом замечаний; после исправления фазы verify и review повторяются |
162
167
  | `внешний` | Любая роль | Запуск завершается со статусом `blocked`, повтор по внешнему событию или вручную |
@@ -171,7 +176,7 @@
171
176
  ### Схема состояний
172
177
 
173
178
  ```text
174
- discover → intake → research → propose → [proposal] → plan → [plan] → cover → [tests] → implement → verify → review → deliver → (merge) → post-merge
179
+ discover → intake → research → propose → [proposal] → plan → [plan] → challenge → cover → [tests] → implement → verify → review → deliver → (merge) → post-merge
175
180
  ▲ ▲ ▲ ▲ │ │
176
181
  │ пробел в фактах │ артефакт │ тесты │ реализация│ │
177
182
  └─────────────────────────────┴─────────────────┴──────────────────┴───────────┴─────────┘
@@ -201,7 +206,7 @@ discover → intake → research → propose → [proposal] → plan → [plan]
201
206
  |---|---|---|---|---|
202
207
  | researcher | Только чтение | Проектную документацию, спецификации, код | `evidence/research.md` | обычный |
203
208
  | planner | Артефакты изменения | Исходный запрос или бриф, evidence, спецификации, правила проекта, код при необходимости | `proposal.md`, `specs/`, `design.md`, `tasks.md` | обычный, pro |
204
- | challenger | Только чтение | Замороженный план или бриф, evidence, правила проекта; в режиме аудита документации всю `.sbox/project/` и код | `evidence/challenge.md`, отчёт `doctor --deep` | pro |
209
+ | challenger | Только чтение | Замороженный план или бриф, evidence, правила проекта; в режиме аудита документации всю `.sbox/project/` и код | `evidence/challenge-N.md`, отчёт `doctor --deep` | pro |
205
210
  | tester | Тестовые файлы и тестовая инфраструктура | Дельты, дизайн, `testing.md`, существующие тесты | Тесты, `coverage.yaml`, `test-plan.md` | обычный, pro |
206
211
  | implementer | Продуктовый код и отметки в `tasks.md`; тестовые файлы защищены | Артефакты изменения, проектную документацию, правила, код | Код | обычный, pro |
207
212
  | reviewer | Только чтение; вердикт привязан к дайджесту change-set | Артефакты, правила, диф, отчёт верификатора; в фазе cover тесты и `coverage.yaml` | `evidence/review-N.md` с disposition и `delivery_narrative`, `evidence/tests-review-N.md` | обычный, pro |
@@ -225,9 +230,9 @@ blocker:
225
230
  category: артефакт | тесты | реализация | внешний | пользователь | нет
226
231
  artifact: tasks # только для категории артефакт
227
232
  message: ...
228
- complexity: # только planner на фазе propose
229
- implementation: обычная | высокая
230
- review: обычная | высокая
233
+ complexity: # planner; challenger может повысить оценку после аудита
234
+ implementation: простая | обычная | высокая
235
+ review: простая | обычная | высокая
231
236
  size: small | normal | large # только planner на фазе propose
232
237
  request: # только researcher: разбор запроса, цитаты сверяются с request.md
233
238
  - { quote: ..., status: подтверждено | противоречит | не проверено, evidence: ... }
@@ -268,7 +273,7 @@ Delivery narrative. При вердикте `готово` ревьюер пиш
268
273
 
269
274
  ### Уровни модели и продолжение сессий
270
275
 
271
- Планировщик оценивает сложность реализации и ревью. По оценке CLI выбирает обычную или pro-модель для тестировщика, реализатора и ревьюера из таблицы в конфиге. Оценка может расти при возвратах, но не снижаться.
276
+ Планировщик отдельно оценивает сложность реализации и ревью: простая, обычная, высокая, учитывая неопределённость и последствия ошибки. Общая функция выбора сопоставляет сложность реализации с simple, medium, complex для implementer/tester, затем берёт model и effort из профиля конкретного раннера. Независимое ревью по умолчанию всегда complex. Оценка может расти при возвратах, но не снижаться; размер изменения не заменяет сложность. Подробная политика и настройка — раздел 18.
272
277
 
273
278
  При возврате к роли CLI продолжает её прошлую сессию по идентификатору, если адаптер среды это умеет. Если нет, создаётся новая сессия, и в неё передаются исходный пакет и текст возврата вместе. Идентификаторы сессий хранятся в `runs/`.
274
279
 
@@ -302,7 +307,7 @@ Delivery narrative. При вердикте `готово` ревьюер пиш
302
307
  test-plan.md # при необходимости
303
308
  evidence/
304
309
  research.md
305
- challenge.md
310
+ challenge-1.md
306
311
  tests-review-1.md
307
312
  review-1.md
308
313
  verify-1.md
@@ -706,7 +711,7 @@ interface AgentRunner {
706
711
  }
707
712
  ```
708
713
 
709
- Реализации: `claude` через Claude Agent SDK (управляемые сессии, разрешения на инструменты, учёт стоимости), `codex` через `codex exec` в неинтерактивном режиме. Если Codex не умеет продолжать сессию, возврат к роли идёт через новую сессию с полным контекстом. Разрешения на команды и пути берутся из `workflow.md`, `testing.md` и списка защищённых файлов.
714
+ Реализации: `claude` через Claude Agent SDK (управляемые сессии, разрешения на инструменты, учёт стоимости), `codex` через `codex exec` в неинтерактивном режиме. Поддержка продолжения проверяется по возможностям CLI; если её нет, возврат к роли идёт через новую сессию с полным контекстом. Разрешения на команды и пути берутся из `workflow.md`, `testing.md` и списка защищённых файлов.
710
715
 
711
716
  Рецепт вызова Codex повторяет проверенный в Suite:
712
717
 
@@ -739,7 +744,13 @@ interface HostMaterials {
739
744
  }
740
745
  ```
741
746
 
742
- Команда `sbox host install --target claude | codex` копирует скиллы из единого источника `assets/skills` (`sbox-run`, `sbox-approve`, `sbox-browser`) в раскладку хоста и генерирует агентов: для Claude Code `.claude/agents/sbox-<role>.md`, где скиллы из `metadata.roles` подключены полем `skills`, потому что субагенты не видят скиллы проекта сами; для Codex сейчас ставятся только скиллы без привязки к хосту (`sbox-approve`, `sbox-browser`) в `.agents/skills`, а `sbox-run` помечен `metadata.hosts: [claude]`, потому что его текст опирается на субагентов Claude Code; агенты ролей и раздел `AGENTS.md` для Codex появятся на этапе 4. Описания агентов берутся из фронтматтера `description` файлов ролей, каркас агента из `assets/hosts/claude/agent.md`, набор инструментов из `runner.claude.allowedTools` и `readOnlyTools` конфига, как в headless-режиме. Все сгенерированные файлы тонкие: они вызывают `sbox next` и `sbox report`, а определения ролей остаются в одном месте. Повторный запуск обновляет файлы, ручные правки в них не предполагаются.
747
+ Команда `sbox host install --target claude | codex` и `sbox init --host` копируют общие скиллы из `assets/skills` без изменений. Для Claude Code генерируются `.claude/agents/sbox-<role>.md` и варианты профилей; скиллы подключаются полем skills. Для Codex генерируются 28 standalone TOML-файлов `.codex/agents/sbox-<role>[-<profile>].toml`: семь активных ролей, базовое имя и три профиля. Имя, описание, model, model_reasoning_effort, sandbox_mode и developer_instructions задаются явно. Скиллы роли фильтруются по хосту и перечисляются путями в инструкциях. Шаблоны живут в assets/hosts; определения ролей и переопределения .sbox/roles общие.
748
+
749
+ Codex получает раздел AGENTS.md между маркерами `<!-- sbox:begin -->` / `<!-- sbox:end -->`; остальной текст сохраняется дословно, повторная установка идемпотентна. Повреждённые маркеры, AGENTS.md-ссылка и чужой файл с именем генерируемого агента останавливают установку до записи материалов. Пользовательский .codex/config.toml не меняется, глобальные настройки и доверие проекту не переключаются. После установки нужна новая сессия Codex; проектные материалы должны быть доверенными средствами хоста. Настройки доступа родительской сессии могут ограничивать или переопределять sandbox агента; инструкции ownership действуют независимо от них.
750
+
751
+ Скилл sbox-run общий: next вызывается с текущим хостом явно. В нативном Codex пользовательский агент возвращает полный ответ родителю, который дословно сохраняет resultFile и сдаёт report; read-only роль не получает запись ради отчёта. CLI сохраняет requested_execution отдельно от фактических данных раннера. Повторное использование агента возможно только внутри того же изменения при совпадении runner/agent/model/effort и доступной функции продолжения. Если клиент не умеет выбирать пользовательских агентов, скилл выполняет один шаг через `sbox run --runner codex --max-runs 1`; headless сам принимает отчёт, поэтому повторный report запрещён. CodexRunner сохраняет thread_id из событий thread.started и продолжает нужную сессию через exec resume <id> при совпадении роли, модели, effort и профиля. Поддержка resume со структурированным выводом проверяется по справке CLI; старый клиент начинает свежую сессию с полным пакетом. Никогда не используется --last. Для resume рабочая директория задаётся cwd процесса, sandbox — через config override. Нативный и headless пути используют один resolver и одинаковый жизненный цикл, включая challenger. Гейты и доставка не утверждаются оркестратором автоматически.
752
+
753
+ Формат Codex сверён с [официальной документацией Subagents](https://learn.chatgpt.com/docs/agent-configuration/subagents) 2026-09-28. Поддержка standalone agents зависит от версии клиента; доступность конкретной модели проверяет провайдер при запуске.
743
754
 
744
755
  ### Отчёты тестов
745
756
 
@@ -776,7 +787,7 @@ interface TestReportAdapter {
776
787
  | Артефакты | `instructions <artifact>`, `validate`, `status`, `coverage`, `changeset` | Инструкция для артефакта, проверка изменения, состояние в JSON (с `revision`, `settled`, `active_run` для внешних вызывающих), покрытие сценариев тестами, запечатанный change-set и сверка дайджеста |
777
788
  | Тесты | `tests check` | Сверка дифа с защищённым списком, запуск тестов из `coverage.yaml` с чтением отчётов |
778
789
  | Решения | `decision promote`, `decision list` | Повышение решения до правила, список действующих правил по области |
779
- | Спецификации | `spec list`, `spec show`, `spec diff`, `spec sync`, `archive` | Чтение истины, сравнение дельты с истиной, выгрузка, применение дельт |
790
+ | Контракт поведения | Отдельный `sbox-contract`: `index`, `show`, `search`, `diff`, `validate`, `apply`; `sbox archive` остаётся в оркестраторе | Чтение истины, проверка и применение дельт; раздел 17 |
780
791
  | События | `events poll`, `events publish` | Опрос и публикация событий координации |
781
792
  | Доставка | `deliver [--check] [--keep-draft]`, `gates poll` | Чеклист готовности и доставка: intent, архив, коммит с ключом, push, пул-реквест; опрос гейтов в комментариях пул-реквеста |
782
793
  | Среда | `ci install --target github \| docker` | Шаблоны workflows GitHub Actions (запуск @spec-box/sdd и тесты с JSON-отчётом) и Dockerfile |
@@ -846,7 +857,7 @@ packages/
846
857
  | 1. Ядро и interactive-режим | Конфиг, `change.yaml`, машина состояний, `next` и `report`, адаптер spec-box, категории документации и структурный `doctor`, формат дизайна с вопросами и правилами, материалы для Claude Code | В репозитории `sync` разработчик проводит одно изменение до пул-реквеста из Claude Code, фазу cover выполняет вручную |
847
858
  | 2. Тесты и headless на GitHub | Роль tester, ИИ-ревью тестов, защита тестов, `coverage.yaml`, верификатор с отчётами до ревьюера, контракт ревьюера с disposition и `delivery_narrative`, запечатывание change-set и привязка вердиктов к дайджесту, ревизия и lock `change.yaml`, receipt запусков, политика одного транспортного повтора, статусы `parked`, `stopped`, `delivery_unknown`, адаптеры сред Claude и Codex с надзором за процессами, `run`, `stop`, `watch`, адаптер GitHub с `git worktree` и идемпотентной доставкой, каналы `cli` и `pr-comments`, архивация в пул-реквесте, CI `sync` на GitHub Actions, Docker-образ и GitHub Action | Изменение в `sync` проходит от тикета до готового к влитию пул-реквеста, человек участвует только на гейтах |
848
859
  | 3. Дискавери и правила | `discover` с дельтами и решениями, критерии достаточности, `discover validate`, повышение решений и проверка правил, `doctor --deep` | Изменение в `sync` по брифу проходит профиль `autonomous` без блокера `пользователь` |
849
- | 4. Arcadia и Magic | Адаптер Arcadia с отдельным `arc mount` на изменение и идемпотентной доставкой в Arcanum, канал `tracker` с проекцией статуса тегами, материалы для Codex | Изменение в Magic проходит headless до готового к влитию пул-реквеста |
860
+ | 4. Arcadia и Magic | Адаптер Arcadia с отдельным `arc mount` на изменение и идемпотентной доставкой в Arcanum, канал `tracker` с проекцией статуса тегами (материалы Codex реализованы отдельно) | Изменение в Magic проходит headless до готового к влитию пул-реквеста |
850
861
  | 5. Несколько репозиториев | Координация, события, опрос и `github-dispatch` | Согласованное изменение в двух репозиториях доходит до двух пул-реквестов с правильным порядком мержа; проект для проверки выбирается, когда он появится |
851
862
  | 6. Расширения | Схема `bugfix` с причинным контрактом и RED-оракулом, wiki и дистилляция, шина событий для Arcadia (адаптер OpenSpec реализован досрочно) | Порядок определяют потребности пилотов |
852
863
 
@@ -874,3 +885,47 @@ Markdown остаётся источником истины. Кеш хранит
874
885
  summary и read_when пишет автор или агент: CLI не генерирует смысловые описания. При обновлении текста автор пересматривает метаданные. revision — версия содержимого, а не свидетельство истинности; автоматическое определение устаревания по коду, семантический поиск и дистилляция остаются расширениями этапа 6.
875
886
 
876
887
  Все команды поддерживают `--json`: результат `{ok:true,data:...}`, ошибка команды `{ok:false,error:{code,message}}`; validate возвращает диагностики в data и код выхода 1 при ошибках. Скилл `assets/skills/sbox-wiki.md` устанавливается обоим хостам и подключается всем ролям; право записи ограничивается полномочиями роли. Wiki-шаблон хранится в `assets/project/wiki.README.md`.
888
+
889
+ ## 17. Отдельный инструмент контракта поведения (реализовано)
890
+
891
+ `sbox-contract` — самостоятельный CLI в том же npm-пакете. Он управляет ожидаемым поведением продукта: capability, требованиями, сценариями и их дельтами. Модели, контракт адаптера, схема конфигурации и сервис применения находятся в `src/contract`; адаптеры форматов остаются в `src/adapters/spec`. Они зависят только от секции `spec`, без конфигурации раннеров, состояния задач и гейтов.
892
+
893
+ ### Границы ответственности
894
+
895
+ `sbox-contract` читает и ищет требования, проверяет структуру и дельты, показывает будущее состояние и применяет изменения. `sbox` управляет ролями, согласованиями, артефактами задачи, архивом, коммитом и PR. `sbox archive` и `sbox deliver` вызывают общий `ContractService` напрямую, без дочернего CLI. Сервис обеспечивает снимок и откат файлов спецификаций при ошибке применения или завершающего действия оркестратора.
896
+
897
+ Группа `sbox spec` удалена. Использования в инструкциях, пакетах ролей и документации переведены на `sbox-contract index/show/diff`. Для материалов уже инициализированных проектов нужно повторить `sbox host install --target claude|codex`. Скилл `assets/skills/sbox-contract.md` общий для обоих хостов. Роли SDD не применяют истину самостоятельно: доступность команды не меняет полномочия роли.
898
+
899
+ ### Конфигурация и команды
900
+
901
+ Корень ищется вверх от --cwd по `.sbox/config.yaml`, `.sbox-contract.yaml`, `.tms.json` или `openspec/specs`. В найденном корне сначала читается секция spec из конфига SDD, иначе из автономного конфига; остальные настройки SDD не нужны. Если конфига нет, формат определяется по файловой структуре. При наличии обоих форматов требуется --format. Без маркеров используется --cwd с spec-box и `specs/**/*.spec-box.yml`. Явный --format переопределяет выбор адаптера.
902
+
903
+ - `init --format spec-box|openspec` создаёт `.sbox-contract.yaml` и папку истины. Существующий конфиг не перезаписывается; в проекте SDD используется его конфиг.
904
+ - `index` возвращает capability с назначением, источником и количеством требований и сценариев; `show <id>` — полную модель, включая нормативный текст.
905
+ - `search <query> --limit N` ищет лексически без учёта регистра в названиях и тексте capability, требований и сценариев. Возвращает сущность, id, источник, текст и оценку совпадения. Лимит по умолчанию 10, допустимо 1–100.
906
+ - `instructions` выдаёт инструкцию формата из assets; `delta init <dir>` создаёт новый каталог дельт и README с этой инструкцией. Существующий каталог не изменяется.
907
+ - `validate [--delta dir]` проверяет истину или истину вместе с дельтой.
908
+ - `diff --delta dir [--preview]` возвращает исходные затронутые capability и операции дельты с требованиями/сценариями. --preview добавляет будущее состояние без записи файлов; отсутствующая в нём capability удаляется. Исходный формат сохраняется адаптером.
909
+ - `apply --delta dir --check` проверяет дельту и структурное будущее состояние, показывает целевые пути и revision. `apply --delta dir --if-match revision` выполняет запись. CLI требует revision; её SHA-256 учитывает модель и байты текущей истины, дельт и целевых файлов. Изменения после проверки приводят к CONTRACT_CONFLICT. Это защита интервала между проверкой и применением, а не сохранённая базовая версия на момент создания дельты.
910
+
911
+ --delta указывает непосредственно на каталог файлов дельт: `*.yml|*.yaml` для spec-box, `<capability>/spec.md` для OpenSpec. Пути относительно --cwd; файл состояния изменения не нужен. Отсутствующая или пустая дельта — ошибка CLI. Все команды имеют --json: `{ok:true,data:...}` или `{ok:false,error:{code,message}}`. Диагностики validate/diff/apply --check возвращаются в data, при наличии ошибок код выхода 1.
912
+
913
+ ### Применение
914
+
915
+ Применение сериализуется файлом `.sbox-contract.lock` в корне проекта с PID владельца. При аварийном завершении lock остаётся: после проверки завершения процесса его можно удалить. Сервис повторно читает состояние под блокировкой, проверяет revision и валидацию, снимает копию затрагиваемых файлов, применяет и проверяет результат. При исключении файлы восстанавливаются, новые удаляются. Запись через симлинки и за пределы корня проекта запрещена. Эта блокировка общая для standalone CLI и доставки SDD; внешние редакторы её не соблюдают. Это откат при обработанной ошибке, не crash-safe транзакция файловой системы.
916
+
917
+ В текущую версию не входят межформатная конвертация, семантический поиск, автоматический merge конкурирующих дельт и выгрузка во внешнюю систему. Архивация задачи и принятие решения о готовности остаются в SDD.
918
+
919
+ ## 18. Профили моделей по раннерам
920
+
921
+ Единый модуль `src/core/model-policy.ts` содержит профили simple/medium/complex, дефолты и функцию resolveModel. Роль определяет профиль, раннер — пару model + effort. Настройки находятся в `runner.claude.profiles` и `runner.codex.profiles`; частично заданные профили дополняются дефолтами. extraConfig Codex не может переопределять model/model_reasoning_effort в обход профиля. Уровни effort проверяются по раннеру (Claude: low/medium/high/xhigh/max; Codex: none/minimal/low/medium/high/xhigh); доступность модели и поддержка конкретного сочетания на стороне провайдера локально не проверяются.
922
+
923
+ Порядок выбора: явный `runner.roleProfiles[role]`; иначе complexity.implementation для implementer/tester (простая → simple, обычная → medium, высокая → complex); иначе дефолт роли. Planner, challenger и reviewer по умолчанию complex, distiller simple, остальные medium. RoleProfiles фиксирует профиль даже при повышенной оценке сложности. Автоматические возвраты только повышают complexity; размер small/normal/large управляет артефактами, а не бюджетом модели. Профиль не назначает модель другому раннеру.
924
+
925
+ Пакет и `sbox next --brief` содержат execution: runner, profile, model, effort, agent. `--runner` у next выбирает среду явно, без флага используется runner.default. Headless передаёт model и effort из того же пакета адаптеру. `sbox models [--runner claude|codex] [--change id]` показывает выбор всех ролей; без --change используются дефолты ролей/явные roleProfiles.
926
+
927
+ Для Claude Code `host install` создаёт по три варианта каждой активной роли (`sbox-<role>-simple|medium|complex`) и базовое имя с дефолтным профилем роли. Model сохраняется точно, без замены полного идентификатора псевдонимом opus/sonnet. Скилл sbox-run вызывает next с --runner текущего хоста и запускает имя из execution.agent. После изменения конфига нужно обновить материалы хоста. Для Codex генерируются TOML-агенты тех же ролей и профилей; execution.agent содержит их имя. Headless использует ту же политику.
928
+
929
+ Headless рассматривает последнюю сессию роли и продолжает её только при совпадении роли, раннера, модели, профиля и effort. Старые записи без профиля/effort не используются для resume. Выбор сохраняется в receipt и истории запусков, в журнале печатаются профиль, модель и effort. Для интерактивного отчёта отдельно сохраняется requested_execution из выданного пакета: это запрошенные настройки, а не подтверждение фактического исполнения хостом. Поля фактического раннера/модели остаются необязательными.
930
+
931
+ Общие runner.models, runner.efforts, runner.defaultEffort отклоняются с инструкцией перейти на профили. Они не игнорируются и автоматически не переносятся, поскольку старая таблица не определяет принадлежность модели раннеру. Базовые идентификаторы моделей SDD сохранены; simple использует прежнюю обычную модель с low, medium — с medium, complex — прежнюю сильную с high. Явные настройки проекта сохраняют приоритет. Это начальная политика качества, не результат измерения качества моделей. complexity.review сохраняется для анализа рисков, но не снижает профиль reviewer. Референс и отличия: docs/research/agentic-openspec-models.md.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spec-box/sdd",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "@spec-box/sdd: автономная реализация продуктовых фич ИИ-агентами",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -15,7 +15,8 @@
15
15
  "bin": {
16
16
  "sbox": "bin/sbox.js",
17
17
  "sbox-browser": "bin/sbox-browser.js",
18
- "sbox-wiki": "bin/sbox-wiki.js"
18
+ "sbox-wiki": "bin/sbox-wiki.js",
19
+ "sbox-contract": "bin/sbox-contract.js"
19
20
  },
20
21
  "files": [
21
22
  "bin",
@@ -1,84 +0,0 @@
1
- import path from 'node:path';
2
- import { archiveChange } from '../../core/archive.js';
3
- import { SboxError } from '../../core/errors.js';
4
- import { changeContext, projectContext } from '../context.js';
5
- import { emit, emitError, formatDiagnostics } from '../output.js';
6
- export function registerSpec(program) {
7
- const spec = program.command('spec').description('Истина спецификаций через адаптер');
8
- spec
9
- .command('list')
10
- .description('Список capability')
11
- .action(async (_opts, cmd) => {
12
- const g = cmd.optsWithGlobals();
13
- try {
14
- const ctx = projectContext(g.cwd);
15
- const truth = await ctx.adapter.readTruth();
16
- const items = truth.map((c) => ({ id: c.id, title: c.title, requirements: c.requirements.length, scenarios: c.requirements.reduce((n, r) => n + r.scenarios.length, 0), source: c.source }));
17
- emit(g, { adapter: ctx.adapter.name, capabilities: items }, (d) => d.capabilities.map((c) => `${c.id}\t${c.title}\t${c.requirements} групп, ${c.scenarios} утверждений\t${c.source ?? ''}`).join('\n') || 'Спецификаций нет.');
18
- }
19
- catch (e) {
20
- emitError(g, e);
21
- process.exitCode = 1;
22
- }
23
- });
24
- spec
25
- .command('show <id>')
26
- .description('Capability целиком')
27
- .action(async (id, _opts, cmd) => {
28
- const g = cmd.optsWithGlobals();
29
- try {
30
- const ctx = projectContext(g.cwd);
31
- const cap = (await ctx.adapter.readTruth()).find((c) => c.id === id);
32
- if (!cap)
33
- throw new SboxError('NO_CAPABILITY', `Capability ${id} не найдена`, 'Список: `sbox spec list`.');
34
- emit(g, { capability: cap }, (d) => [`# ${d.capability.title} (${d.capability.id})`, d.capability.purpose ?? '', ...d.capability.requirements.flatMap((r) => [`## ${r.title}`, ...r.scenarios.map((s) => `- ${s.title}${s.description ? `\n ${s.description.replace(/\n/g, '\n ')}` : ''}`)])].join('\n'));
35
- }
36
- catch (e) {
37
- emitError(g, e);
38
- process.exitCode = 1;
39
- }
40
- });
41
- spec
42
- .command('diff')
43
- .description('Дельты изменения относительно истины')
44
- .option('--change <id>')
45
- .action(async (opts, cmd) => {
46
- const g = cmd.optsWithGlobals();
47
- try {
48
- const ctx = changeContext(g.cwd, opts.change);
49
- const truth = await ctx.adapter.readTruth();
50
- const deltas = await ctx.adapter.readDelta(path.join(ctx.dir, 'specs'));
51
- const diagnostics = ctx.adapter.validate(truth, deltas);
52
- emit(g, { deltas, diagnostics }, (d) => [
53
- ...d.deltas.map((delta) => [`# ${delta.capabilityId}${delta.isNew ? ' (новая)' : ''} — ${delta.source}`, ...delta.ops.map((op) => op.op === 'add-requirement' ? `+ ${op.requirement.title} (${op.requirement.scenarios.length})` : op.op === 'modify-requirement' ? `~ ${op.requirement.title} (${op.requirement.scenarios.length})` : op.op === 'remove-requirement' ? `- ${op.requirementTitle}${op.scenarios ? ` [${op.scenarios.length} утв.]` : ''}` : `→ ${op.from} ⇒ ${op.to}`)].join('\n')),
54
- '',
55
- formatDiagnostics(d.diagnostics),
56
- ].join('\n'));
57
- }
58
- catch (e) {
59
- emitError(g, e);
60
- process.exitCode = 1;
61
- }
62
- });
63
- program
64
- .command('archive')
65
- .description('Применить дельты к истине и перенести изменение в архив')
66
- .option('--change <id>')
67
- .option('--force', 'применить несмотря на ошибки валидации')
68
- .action(async (opts, cmd) => {
69
- const g = cmd.optsWithGlobals();
70
- try {
71
- const ctx = changeContext(g.cwd, opts.change);
72
- if (ctx.change.phase !== 'deliver' && !opts.force) {
73
- throw new SboxError('NOT_DELIVERABLE', `Изменение в фазе ${ctx.change.phase}, а не deliver.`, 'Доведите изменение до фазы deliver или используйте --force.');
74
- }
75
- const result = await archiveChange(ctx.root, ctx.config, ctx.adapter, ctx.dir, ctx.change, { force: opts.force });
76
- emit(g, { archivedTo: path.relative(ctx.root, result.archivedTo), appliedFiles: result.appliedFiles, diagnostics: result.diagnostics }, (d) => [`Архив: ${d.archivedTo}`, ...d.appliedFiles.map((f) => ` ~ ${f}`), formatDiagnostics(d.diagnostics)].join('\n'));
77
- }
78
- catch (e) {
79
- emitError(g, e);
80
- process.exitCode = 1;
81
- }
82
- });
83
- }
84
- //# sourceMappingURL=spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../src/cli/commands/spec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAIlE,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC;IAEtF,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,KAAK,EAAE,KAAc,EAAE,GAAY,EAAE,EAAE;QAC7C,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAa,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC7L,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,YAAY,WAAW,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,CAAC;QACjO,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,oBAAoB,CAAC;SACjC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,KAAc,EAAE,GAAY,EAAE,EAAE;QACzD,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAa,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACrE,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,2BAA2B,CAAC,CAAC;YAC3G,IAAI,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/S,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,eAAe,CAAC;SACvB,MAAM,CAAC,KAAK,EAAE,IAAyB,EAAE,GAAY,EAAE,EAAE;QACxD,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAa,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;YACxE,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACxD,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CACrC;gBACE,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,iBAAiB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,KAAK,KAAK,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,KAAK,KAAK,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,gBAAgB,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACne,EAAE;gBACF,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC;aACjC,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,eAAe,CAAC;SACvB,MAAM,CAAC,SAAS,EAAE,wCAAwC,CAAC;SAC3D,MAAM,CAAC,KAAK,EAAE,IAA0C,EAAE,GAAY,EAAE,EAAE;QACzE,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAa,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAClD,MAAM,IAAI,SAAS,CAAC,iBAAiB,EAAE,oBAAoB,GAAG,CAAC,MAAM,CAAC,KAAK,iBAAiB,EAAE,6DAA6D,CAAC,CAAC;YAC/J,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAClH,IAAI,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpQ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec-adapter.js","sourceRoot":"","sources":["../../src/core/spec-adapter.ts"],"names":[],"mappings":"AA2BA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;AAEvD,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,OAA2B;IAC3E,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAc;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec-model.js","sourceRoot":"","sources":["../../src/core/spec-model.ts"],"names":[],"mappings":"AAqDA,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;SAChC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC;AAC5B,CAAC"}