zorya-classifier 0.2.0 → 0.2.2

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 (140) hide show
  1. package/README.md +24 -8
  2. package/dist/app/classifier-config.d.ts +30 -0
  3. package/dist/app/classifier-config.js +46 -0
  4. package/dist/app/classifier-contracts.d.ts +32 -0
  5. package/dist/app/classifier-contracts.js +1 -0
  6. package/dist/app/classifier-representation.d.ts +5 -0
  7. package/dist/app/classifier-representation.js +33 -0
  8. package/dist/app/classifier-runtime.d.ts +7 -0
  9. package/dist/app/classifier-runtime.js +71 -0
  10. package/dist/app/classifier-spatial.d.ts +31 -0
  11. package/dist/app/classifier-spatial.js +78 -0
  12. package/dist/app/cli-arguments.d.ts +2 -2
  13. package/dist/app/create-classifier.d.ts +4 -29
  14. package/dist/app/create-classifier.js +37 -237
  15. package/dist/cli.js +1 -1
  16. package/dist/entities/classification.d.ts +98 -0
  17. package/dist/entities/classification.js +28 -0
  18. package/dist/entities/contracts.d.ts +6 -471
  19. package/dist/entities/contracts.js +6 -97
  20. package/dist/entities/decision.d.ts +211 -0
  21. package/dist/entities/decision.js +33 -0
  22. package/dist/entities/geometry.d.ts +37 -0
  23. package/dist/entities/geometry.js +26 -0
  24. package/dist/entities/image.d.ts +39 -0
  25. package/dist/entities/image.js +15 -0
  26. package/dist/entities/localization.d.ts +125 -0
  27. package/dist/entities/localization.js +13 -0
  28. package/dist/entities/object-proposals.d.ts +4 -1
  29. package/dist/entities/segmentation-metadata.d.ts +70 -0
  30. package/dist/entities/segmentation-metadata.js +21 -1
  31. package/dist/entities/segmentation-verification.d.ts +1 -0
  32. package/dist/entities/segmentation.d.ts +6 -1
  33. package/dist/entities/validation.d.ts +2 -0
  34. package/dist/entities/validation.js +9 -0
  35. package/dist/entities/whole-object.d.ts +4 -0
  36. package/dist/features/choice-beam-layout.js +2 -7
  37. package/dist/features/proposals/presentation.d.ts +21 -0
  38. package/dist/features/proposals/presentation.js +122 -0
  39. package/dist/features/proposals/validation.d.ts +138 -0
  40. package/dist/features/proposals/validation.js +125 -0
  41. package/dist/features/segmentation/box-check.js +10 -23
  42. package/dist/features/segmentation/mask.js +2 -7
  43. package/dist/features/segmentation/region-result.d.ts +18 -0
  44. package/dist/features/segmentation/region-result.js +171 -0
  45. package/dist/features/segmentation/source-mask.d.ts +6 -0
  46. package/dist/features/segmentation/source-mask.js +32 -0
  47. package/dist/features/segmentation/validation.d.ts +9 -0
  48. package/dist/features/segmentation/validation.js +94 -0
  49. package/dist/infrastructure/decision-transport/errors.d.ts +8 -0
  50. package/dist/infrastructure/decision-transport/errors.js +34 -0
  51. package/dist/infrastructure/decision-transport/images.d.ts +1 -0
  52. package/dist/infrastructure/decision-transport/images.js +52 -0
  53. package/dist/infrastructure/{openrouter-common.d.ts → decision-transport/request.d.ts} +6 -15
  54. package/dist/infrastructure/decision-transport/request.js +162 -0
  55. package/dist/infrastructure/decision-transport/response.d.ts +1 -0
  56. package/dist/infrastructure/decision-transport/response.js +72 -0
  57. package/dist/infrastructure/decision-transport/route-identity.d.ts +11 -0
  58. package/dist/infrastructure/decision-transport/route-identity.js +23 -0
  59. package/dist/infrastructure/openrouter-vision.js +1 -1
  60. package/dist/infrastructure/openrouter.js +7 -19
  61. package/dist/infrastructure/raster.js +3 -8
  62. package/dist/infrastructure/segmentation/grabcut/index.d.ts +5 -1
  63. package/dist/infrastructure/segmentation/grabcut/index.js +6 -5
  64. package/dist/infrastructure/segmentation/grabcut/masks.d.ts +49 -0
  65. package/dist/infrastructure/segmentation/grabcut/masks.js +89 -0
  66. package/dist/infrastructure/segmentation/grabcut/model-asset.d.ts +4 -0
  67. package/dist/infrastructure/segmentation/grabcut/model-asset.js +4 -0
  68. package/dist/infrastructure/segmentation/grabcut/runtime.d.ts +70 -0
  69. package/dist/infrastructure/segmentation/grabcut/runtime.js +96 -0
  70. package/dist/infrastructure/segmentation/grabcut/worker-inference.d.ts +4 -43
  71. package/dist/infrastructure/segmentation/grabcut/worker-inference.js +4 -187
  72. package/dist/infrastructure/segmentation/mobile-sam/index.d.ts +3 -58
  73. package/dist/infrastructure/segmentation/mobile-sam/index.js +2 -472
  74. package/dist/infrastructure/segmentation/mobile-sam/input.d.ts +46 -0
  75. package/dist/infrastructure/segmentation/mobile-sam/input.js +83 -0
  76. package/dist/infrastructure/segmentation/mobile-sam/model-assets.d.ts +8 -0
  77. package/dist/infrastructure/segmentation/mobile-sam/model-assets.js +8 -0
  78. package/dist/infrastructure/segmentation/mobile-sam/object-proposals.d.ts +7 -0
  79. package/dist/infrastructure/segmentation/mobile-sam/object-proposals.js +124 -0
  80. package/dist/infrastructure/segmentation/mobile-sam/options.d.ts +43 -0
  81. package/dist/infrastructure/segmentation/mobile-sam/options.js +19 -0
  82. package/dist/infrastructure/segmentation/mobile-sam/proposal-masks.d.ts +26 -0
  83. package/dist/infrastructure/segmentation/mobile-sam/proposal-masks.js +71 -0
  84. package/dist/infrastructure/segmentation/mobile-sam/segmentation-masks.d.ts +112 -0
  85. package/dist/infrastructure/segmentation/mobile-sam/segmentation-masks.js +230 -0
  86. package/dist/infrastructure/segmentation/mobile-sam/segmenter.d.ts +22 -0
  87. package/dist/infrastructure/segmentation/mobile-sam/segmenter.js +268 -0
  88. package/dist/infrastructure/segmentation/mobile-sam/worker-expand.d.ts +7 -0
  89. package/dist/infrastructure/segmentation/mobile-sam/worker-expand.js +188 -0
  90. package/dist/infrastructure/segmentation/mobile-sam/worker-inference.d.ts +6 -149
  91. package/dist/infrastructure/segmentation/mobile-sam/worker-inference.js +6 -845
  92. package/dist/infrastructure/segmentation/mobile-sam/worker-models.d.ts +14 -0
  93. package/dist/infrastructure/segmentation/mobile-sam/worker-models.js +72 -0
  94. package/dist/infrastructure/segmentation/mobile-sam/worker-proposals.d.ts +7 -0
  95. package/dist/infrastructure/segmentation/mobile-sam/worker-proposals.js +159 -0
  96. package/dist/infrastructure/segmentation/mobile-sam/worker-segment.d.ts +4 -0
  97. package/dist/infrastructure/segmentation/mobile-sam/worker-segment.js +126 -0
  98. package/dist/infrastructure/segmentation/native-protocol.d.ts +59 -34
  99. package/dist/infrastructure/segmentation/native-protocol.js +26 -16
  100. package/dist/infrastructure/segmentation/proposal-presentation-input.d.ts +20 -0
  101. package/dist/infrastructure/segmentation/proposal-presentation-input.js +107 -0
  102. package/dist/infrastructure/segmentation/proposal-presentation-pixels.d.ts +8 -0
  103. package/dist/infrastructure/segmentation/proposal-presentation-pixels.js +93 -0
  104. package/dist/infrastructure/segmentation/proposal-presentation.js +10 -201
  105. package/dist/infrastructure/vision-chat/options.d.ts +62 -0
  106. package/dist/infrastructure/vision-chat/options.js +46 -0
  107. package/dist/infrastructure/vision-chat/request.d.ts +23 -0
  108. package/dist/infrastructure/vision-chat/request.js +109 -0
  109. package/dist/infrastructure/vision-chat/response.d.ts +3 -0
  110. package/dist/infrastructure/vision-chat/response.js +105 -0
  111. package/dist/infrastructure/vision-chat.d.ts +4 -61
  112. package/dist/infrastructure/vision-chat.js +8 -271
  113. package/dist/openai-compatible.js +1 -1
  114. package/dist/processes/extract-from-region.js +11 -216
  115. package/dist/processes/extract.d.ts +2 -8
  116. package/dist/processes/extract.js +12 -128
  117. package/dist/processes/proposal-location.js +5 -251
  118. package/docs/0.2.0-plan.md +3 -3
  119. package/docs/README.ru.md +42 -23
  120. package/docs/acceptance.md +5 -5
  121. package/docs/agents.ru.md +95 -0
  122. package/docs/api.md +4 -2
  123. package/docs/architecture.md +33 -5
  124. package/docs/architecture.ru.md +146 -0
  125. package/docs/benchmarks.md +4 -2
  126. package/docs/development.ru.md +141 -0
  127. package/docs/operations.md +4 -4
  128. package/docs/provenance.json +5 -1
  129. package/docs/publishing.md +8 -0
  130. package/docs/refactoring-plan.ru.md +183 -0
  131. package/docs/v02-usage.md +8 -6
  132. package/docs/vision-results.md +2 -0
  133. package/package.json +5 -3
  134. package/dist/infrastructure/boundary-view.d.ts +0 -2
  135. package/dist/infrastructure/boundary-view.js +0 -263
  136. package/dist/infrastructure/openrouter-common.js +0 -317
  137. package/dist/infrastructure/text-representation.d.ts +0 -23
  138. package/dist/infrastructure/text-representation.js +0 -226
  139. package/docs/evidence/v02/categorical-heldout-v4/README.md +0 -35
  140. package/docs/evidence/v02/proposal-resource-soak-261dc23.md +0 -15
package/docs/README.ru.md CHANGED
@@ -1,26 +1,42 @@
1
1
  # Zorya Classifier: руководство
2
2
 
3
- Версия 0.2 добавляет прозрачный PNG, бинарную маску, её рамку и центр. Прежний поиск области служит подсказкой для сегментации всего исходного изображения. Затем decision проверяет рамку; допускаются одно расширение маски и повторная проверка. [Руководство](v02-usage.md) описывает API, CLI и владение ресурсами.
3
+ Версия 0.2 добавляет прозрачный PNG, бинарную маску, её рамку и центр. Прежний поиск области служит подсказкой для сегментации всего исходного изображения. Затем порт решений проверяет рамку; допускаются одно расширение маски и повторная проверка. [Руководство](v02-usage.md) описывает API, CLI и владение ресурсами.
4
4
 
5
5
  [Независимый тест 80 случаев](evidence/v02/region-seeded-heldout-v3/README.md) прошёл согласованные критерии, но показал ограниченную полноту: 26/60 попаданий в область объекта и 8/60 полных рамок, без ложных выделений на 20 отрицательных случаях. Из 30 эталонных масок восемь достигли IoU 0,8, три не достигли, для 19 предсказание отсутствовало. Это результаты одной явно настроенной комбинации Luna/OpenAI и MobileSAM, а не гарантия для любой модели или игры.
6
6
 
7
7
  Сравнение шести способов передачи изображения текстом завершено на свежих фотографиях и реальном интерфейсе: ни один не прошёл требования локализации. [Результаты и ограничения](evidence/v02/fresh-text/README.md) сохранены, публичный экспериментальный режим явно возвращает `UNSUPPORTED`.
8
8
 
9
- Zorya Classifier — библиотека для Node.js и TypeScript, которая помогает приложению принимать решения по тексту и изображениям. Библиотека не выбирает и не подключает модель за приложение: клиент получает явно переданный `DecisionPort` — готовый адаптер с выбранными настройками или собственную реализацию. Модель и провайдер в примерах — лишь варианты интеграции, не значения по умолчанию. Код распространяется по MIT; веса модели в поставку не входят, запросы удалённых моделей оплачиваются отдельно; можно подключить и свой локальный сервер. Совместимость и качество зависят от выбранного маршрута. Более мощная модель может помочь, но улучшение точности не гарантировано. Проверенные комбинации и результаты перечислены в [таблице моделей](vision-results.md).
9
+ Zorya Classifier — библиотека для Node.js и TypeScript с поддерживаемой классификацией по тексту и изображениям и экспериментальной, не квалифицированной для общего применения пространственной локализацией и извлечением объектов. Библиотека не выбирает и не подключает модель за приложение: клиент получает явно переданный `DecisionPort` — готовый адаптер с выбранными настройками или собственную реализацию. Модель и провайдер в примерах — лишь варианты интеграции, не значения по умолчанию. Код распространяется по MIT; веса модели в поставку не входят, запросы удалённых моделей оплачиваются отдельно; можно подключить и свой локальный сервер. Совместимость и качество зависят от выбранного маршрута. Более мощная модель может помочь, но улучшение точности не гарантировано. Проверенные комбинации и результаты перечислены в [таблице моделей](vision-results.md).
10
10
 
11
11
  Это самостоятельная библиотека: ей не нужны Zorya Games, Electron, база данных или игровой процесс. Её можно встроить в сервер, бота, инструмент обработки фотографий или собственный HTTP-сервис. Готовый постоянно работающий HTTP-сервер в пакет не входит.
12
12
 
13
+ ## Статус возможностей
14
+
15
+ Дальнейшие эксперименты по точности пространственных сценариев остановлены; ни одна стратегия локализации, извлечения или предложений масок не продвигается для общего использования. Исторические метрики в `docs/evidence/**` сохранены без переинтерпретации.
16
+
17
+ | Возможность | Статус | Примечание |
18
+ | --------------------------------------------- | ---------------- | ------------------------------------------------------------------------------ |
19
+ | `classify` с явным `DecisionPort` | Поддерживается | Один закрытый ID класса; без заявления об универсальной точности модели |
20
+ | `locate` (сетка регионов) | Экспериментально | Гипотеза по ячейке, не геометрия целого объекта и не доказательство отсутствия |
21
+ | `RefinementPort` | Экспериментально | Без общей квалификации качества |
22
+ | `locate({ mode: 'whole-object' })` | Экспериментально | Интервалы или сегментация вызывающего; без квалификации |
23
+ | `extract`, `SegmentationPort`, проверка рамки | Экспериментально | Структурный успех ≠ семантическая точность маски |
24
+ | `objectProposals`, нативные фабрики | Экспериментально | На стороне вызывающего; без квалификации |
25
+ | `experimental-text` | Отклонено | `UNSUPPORTED`, пока профиль не пройдёт отбор |
26
+
27
+ Heldout region-seeded (один задокументированный рецепт): 26/60 попаданий seed на позитивах; 8/60 полных рамок объекта; на 30 эталонных масках — 8 с IoU 0,8, 3 неудачи, 19 без предсказания. H8 DEV: 7/9 позитивов и 2/3 ложных выхода, без квалификации. Узкий исторический admission — не общая пространственная квалификация.
28
+
13
29
  ## Что умеет
14
30
 
15
- | Задача | API | Результат |
16
- | ---------------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------- |
17
- | Распределить обращения по отделам, определить намерение | `classify` с текстом | Один из заданных классов и ранжирование вариантов |
18
- | Проверить наличие объекта или выбрать категорию фотографии | `classify` с изображением | Один из заданных классов |
19
- | Оценить изображение с текстовым условием | `classify` с текстом и изображением | Класс с учётом обоих входов |
20
- | Найти примерную область предмета, значка или указателя | `locate` | Ячейка в координатах исходного изображения либо явная неопределённость/отсутствие |
21
- | Получить маску, рамку, центр и прозрачный вырез предмета | `extract` с явным сегментатором | Геометрия и вырез, выведенные из пикселей маски |
31
+ | Задача | Статус | API | Результат |
32
+ | ---------------------------------------------------------- | ---------------- | ----------------------------------- | --------------------------------------------------------------------------------- |
33
+ | Распределить обращения по отделам, определить намерение | Поддерживается | `classify` с текстом | Один из заданных классов и ранжирование вариантов |
34
+ | Проверить наличие объекта или выбрать категорию фотографии | Поддерживается | `classify` с изображением | Один из заданных классов |
35
+ | Оценить изображение с текстовым условием | Поддерживается | `classify` с текстом и изображением | Класс с учётом обоих входов |
36
+ | Найти примерную область предмета, значка или указателя | Экспериментально | `locate` | Ячейка в координатах исходного изображения либо явная неопределённость/отсутствие |
37
+ | Получить маску, рамку, центр и прозрачный вырез предмета | Экспериментально | `extract` с явным сегментатором | Геометрия и вырез, выведенные из пикселей маски |
22
38
 
23
- Для `extract` после сегментации модель получает исходную картинку с рамкой маски и отметкой прежней найденной области. Она выбирает один ответ: весь видимый объект внутри, нужно расширение или определить не удалось. При необходимости сегментатор один раз ищет внешнюю маску, содержащую прежние пиксели; её рамка проверяется повторно. Максимум получается пять модельных запросов: три на поиск области и два на проверку. Если подтверждения нет, библиотека возвращает неопределённость без частичного выреза. `verification` сохраняет проверки и результат расширения. Рамка и центр всегда вычисляются из маски; проверка рамки не гарантирует точности каждого пикселя. Своя модель подключается через `DecisionPort`, отдельная проверка — через `segmentationBoxCheck`.
39
+ Для `extract` после сегментации порт решений получает полный исходник с рамкой из маски и исходной подсказкой `seed`. Ответ закрыт: `complete` (можно вернуть результат и опциональный вырез), `needs-expansion` (не более одного расширения охватывающей маски и одной финальной проверки; повторный `complete` после финальной проверки тоже допускает результат) или `unknown` (неразрешённая проверка, нет поддержки расширения, нет действительной охватывающей маски или провал финальной проверки — второго расширения нет). Внутри одного `extract` со встроенным `locate` — до трёх запросов на поиск области и до двух закрытых проверок рамки. Без подтверждения библиотека возвращает неопределённость и не публикует частичный вырез. Рамка и центр только из пикселей маски; успешная проверка рамки не доказывает идеальную сегментацию по пикселям. Порт решений подключается через `DecisionPort`; сегментатор остаётся на стороне вызывающего.
24
40
 
25
41
  Сконфигурированный `DecisionPort` выполняет запросы по контракту библиотеки. `classify` делает один запрос, а `locate` — до трёх последовательных запросов: крупная сетка → уточнение в четырёх выбранных областях → сравнение четырёх увеличенных кандидатов. Проверки присутствия входят в те же запросы. Порт отвечает за ответы, координаты вычисляет код.
26
42
 
@@ -28,7 +44,7 @@ Zorya Classifier — библиотека для Node.js и TypeScript, кото
28
44
 
29
45
  ## Установка и ключ
30
46
 
31
- Нужен Node.js 22.12 или новее. Windows и Linux проверены; macOS отдельно не проверялась. Зависимости исполнения — Zod и Sharp, включая подходящий платформе нативный модуль Sharp.
47
+ Нужен Node.js 22.12 или новее. Сводка измеренных контрольных точек рефакторинга (Linux Node 22/24, Windows, интерпретатор Python) и статус волн 1–9 — в [плане рефакторинга](refactoring-plan.ru.md); здесь не дублируется. Зависимости среды выполнения — Zod и Sharp, включая платформенный нативный модуль Sharp.
32
48
 
33
49
  Исходники: [zoomplus/zorya-classifier](https://github.com/zoomplus/zorya-classifier). Пакет: [zorya-classifier в npm](https://www.npmjs.com/package/zorya-classifier). Установка из реестра:
34
50
 
@@ -36,7 +52,7 @@ Zorya Classifier — библиотека для Node.js и TypeScript, кото
36
52
  npm install zorya-classifier
37
53
  ```
38
54
 
39
- Для локального/релизного архива также работает `npm install ./zorya-classifier-0.1.0.tgz`.
55
+ Для локального/релизного архива также работает `npm install ./zorya-classifier-0.2.0.tgz` (имя следует версии в `package.json`; это не заявление о новой публикации в npm).
40
56
 
41
57
  Скопируйте пример конфигурации в локальный `.env` и заполните значение `OPENROUTER_API_KEY` своим ключом. В репозитории `.env` исключён из Git; в своём проекте тоже добавьте это исключение. Не помещайте ключ в браузерный React-код, приложение клиента или публичный репозиторий. Вызовы модели выполняйте на доверенном сервере.
42
58
 
@@ -111,9 +127,9 @@ const result = await client.classify({
111
127
 
112
128
  Для одной картинки поле `text` можно опустить. Принимаются `Uint8Array` и `Buffer` с одним PNG/JPEG/WebP: до 16 MiB и 16 777 216 декодированных пикселей. Ссылки на изображения публичный API не загружает — скачивание, права доступа и ограничения внешних URL остаются у вызывающего приложения.
113
129
 
114
- ## Поиск объекта и координаты
130
+ ## Поиск объекта и координаты (экспериментально)
115
131
 
116
- Также внутри `try`:
132
+ Обычный `locate` экспериментален и не квалифицирован для общего применения. Также внутри `try`:
117
133
 
118
134
  ```js
119
135
  const result = await client.locate({
@@ -142,9 +158,9 @@ if (result.status === 'located') {
142
158
  | `unknown` | Неуверенность, противоречие, отсутствие цели среди кандидатов или невозможная сетка | Уточнить цель, взять более подходящее изображение или вернуть пользователю неопределённость |
143
159
  | Исключение `ClassifierError` | Ошибка входа, сети, протокола, бюджета или жизненного цикла | Обработать код ошибки; не показывать её как отсутствие объекта |
144
160
 
145
- Если нужны маска, рамка или центр объекта, используйте `extract` с явно созданным сегментатором. Обычный `locate` сначала находит регион-кандидат; затем сегментатор получает seed-подсказку на всём ориентированном исходном изображении. Рамка и центр вычисляются по реальным пикселям маски, без отдельного поиска границ или подтверждения рамки языковой моделью. Пример и детали владения ресурсами приведены в [руководстве 0.2](v02-usage.md). Это технический путь обработки, а не гарантия точности на всех фото.
161
+ Если нужны маска, рамка или центр объекта, используйте `extract` с явно созданным сегментатором. Обычный `locate` сначала находит регион-кандидат; затем сегментатор получает подсказку `seed` на всём ориентированном исходном изображении. Рамка и центр вычисляются по реальным пикселям маски. После сегментации **текущий** основной поток выполняет до **двух** закрытых проверок рамки на полном исходнике (`complete` / `needs-expansion` / `unknown`) через `DecisionPort`, с не более чем одним расширением маски и финальной проверкой; обрезка, масштаб и поля вокруг изображения сохраняют соответствие исходника и маски, а подготовка вида для проверки идёт через `RasterPort.imageState` на полном холсте. Пример и владение ресурсами — [руководство 0.2](v02-usage.md), [architecture.ru.md](architecture.ru.md). Это технический путь, а не гарантия точности на всех фото.
146
162
 
147
- В проверенном сценарии v2 приложение сначала вызывает `classify` для наличия цели и запускает `extract` только после ответа `present`. Это явная композиция приложения: один запрос классификации плюс до трёх запросов поиска. Сам `extract` дополнительную классификацию не вставляет. Ошибку классификации нельзя выдавать за отсутствие цели; обе операции должны использовать общий сигнал отмены и абсолютный срок выполнения.
163
+ В типичной композиции приложение сначала вызывает `classify` для наличия цели и запускает `extract` только после ответа `present`. Это **явная** композиция: **1** запрос классификации + до **3** запросов `locate` + до **2** запросов проверки рамки внутри `extract` — **до 6** запросов порта решений суммарно. Сам `extract` отдельную классификацию не подставляет. Ошибку классификации нельзя выдавать за отсутствие цели. Вызывающий **может** передать один `AbortSignal` или общий предельный срок на **несколько** вызовов в своём сценарии, но библиотека держит **один абсолютный предельный срок на каждую отдельную операцию**, включая ожидание в очереди; **два** отдельных вызова **не** делят один предельный срок автоматически.
148
164
 
149
165
  Встроенный MobileSAM получает точку в центре найденной области и обрабатывает весь исходник; текст названия предмета он не понимает. Поэтому иногда он выделяет деталь, например фару вместо автомобиля. Успешный `extracted` подтверждает корректность маски и файлов, а точность распознавания оценивается отдельно. На полном DEV40 для v2 было 18/30 попаданий области в рамку цели, 5/30 совпадений рамки маски и 0 ложных вырезок на 10 отрицательных примерах. Это разные метрики. [Независимый отчёт](evidence/v02/region-seeded-dev-v2/README.md) сохраняет ошибки и ограничения; другой сегментатор подключается через тот же `SegmentationPort`.
150
166
 
@@ -152,7 +168,7 @@ if (result.status === 'located') {
152
168
 
153
169
  Переиспользуйте один `client` на жизненный цикл сервиса. По умолчанию одновременно выполняются две операции, в очереди допускается 16, общий тайм-аут — 45 секунд, включая ожидание очереди и обработку картинки. Параметры можно задать в `createClassifier`; максимумы — 4 операции, 32 ожидающих и 120 секунд. При переполнении возвращается `CAPACITY`, вместо неограниченного накопления задач.
154
170
 
155
- Для отмены передайте `signal`. Например, этот вызов завершается не позднее тайм-аута сигнала с учётом физического освобождения нативных ресурсов:
171
+ Для отмены передайте `signal`. Операция перестаёт принимать результат после отмены или тайм-аута, но **может** удерживать слот и завершать физическую работу (HTTP, Sharp, принадлежащий нативный дочерний процесс) до фактического завершения — момент возврата из вызова по календарному времени **не** обещает мгновенного освобождения всех нативных ресурсов. Пример:
156
172
 
157
173
  ```js
158
174
  const result = await client.classify({
@@ -236,7 +252,7 @@ const client = createClassifier({ decision })
236
252
 
237
253
  [Таблица проверенных моделей](vision-results.md) содержит названия, провайдеров, число примеров, ошибки, точность, задержки и цену. Там отдельно указаны полноценная проверка на корпусе, короткий screening и тесты адаптера с искусственным сервером. Необозначенная модель не считается автоматически проверенной.
238
254
 
239
- Исторический Jev-прогон дал 55/60 на фото и 30/30 на авторских текстовых примерах. Это baseline прежнего адаптера, а не доказательство качества или превосходства другой модели. Результаты не позволяют предполагать, что более мощная модель обязательно повысит точность. Подробности и исходные ошибки сохранены в [исторических результатах](results.md). Локализация остаётся экспериментальной; ячейка не является точной маской или центром объекта.
255
+ Исторический Jev-прогон дал 55/60 на фото и 30/30 на авторских текстовых примерах. Это исходный эталон прежнего адаптера, а не доказательство качества или превосходства другой модели. Результаты не позволяют предполагать, что более мощная модель обязательно повысит точность. Подробности и исходные ошибки сохранены в [исторических результатах](results.md). Локализация остаётся экспериментальной; ячейка не является точной маской или центром объекта.
240
256
 
241
257
  ## Разработка и следующие документы
242
258
 
@@ -248,11 +264,14 @@ npm run pack:check
248
264
  npm run format:check
249
265
  ```
250
266
 
251
- `check` включает секреты, TypeScript, ESLint, границы слоёв, неиспользуемый код, тесты и сборку. Husky проверяет добавленные в Git версии файлов. `pack:check` устанавливает архив в независимый проект, проверяет его файлы и API. Эти проверки не вызывают реальную модель.
267
+ `check` включает секреты, TypeScript, ESLint, границы слоёв, неиспользуемый код, тесты и сборку. Husky проверяет добавленные в Git версии файлов. `pack:check` устанавливает архив в независимый проект-потребитель, проверяет его файлы и API. Эти проверки не вызывают реальную модель.
252
268
 
253
269
  - [Полный контракт API](api.md): типы, лимиты, формат метаданных, округление баллов.
254
- - [Архитектура](architecture.md): слои, порты, отмена и владение ресурсами.
270
+ - [Архитектура](architecture.md) / [architecture.ru.md](architecture.ru.md): слои, порты, согласованность координат изображения и маски, жизненный цикл.
271
+ - [Разработка](development.ru.md): установка, каталог тестов (`H5`, `H10` и группа `local-evidence`), секреты, архив пакета.
272
+ - [Агенты и Composer](agents.ru.md): роли главного оркестратора, координатора и исполнителя Composer; видимость волн рефакторинга.
273
+ - [План рефакторинга](refactoring-plan.ru.md): волны 1–9 и платформенные журналы/отчёты.
255
274
  - [Эксплуатация](operations.md): интеграция в сервис, расходы и завершение работы.
256
- - [Воспроизведение benchmark](benchmarks.md): лицензированные фотографии и отдельный запуск платных проверок.
257
- - [Безопасность](../SECURITY.md): ключи, Git, npm-архивы и ограничения сканирования.
258
- - [Подготовка публикации](publishing.md): GitHub/npm и необходимая авторизация владельца.
275
+ - [Воспроизведение каталога `benchmarks`](benchmarks.md): лицензированные фотографии и отдельный запуск платных проверок.
276
+ - [Безопасность](https://github.com/zoomplus/zorya-classifier/blob/main/SECURITY.md): ключи, Git, npm-архивы и ограничения сканирования.
277
+ - [Подготовка публикации](publishing.md): реестры `GitHub` и `npm` и необходимая авторизация владельца.
@@ -1,6 +1,6 @@
1
1
  # Acceptance: standalone library
2
2
 
3
- This acceptance concerns the extracted MIT Node.js library, not the Zorya desktop application, installer, microphone or game session. The caller supplies a `DecisionPort` or explicitly configures an adapter; model/provider recipes below are examples, not library defaults. Ordinary vision chat, direct OpenAI-compatible servers and native decisions are all supported. Jev is optional historical compatibility.
3
+ This acceptance concerns the extracted MIT Node.js library, not the Zorya desktop application, installer, microphone or game session. The caller supplies a `DecisionPort` or explicitly configures an adapter; model/provider recipes below are examples, not library defaults. Closed `classify` and explicitly configured provider/transport adapters are supported integration paths. Region `locate`, whole-object location, extraction, `RefinementPort`, segmentation/box-check composition, `objectProposals`, and native segmentation factories are experimental and unqualified; public API symbols carry `@experimental`. Further spatial accuracy experiments are stopped; no strategy is promoted. Jev is optional historical compatibility.
4
4
 
5
5
  ## Current 0.2 acceptance
6
6
 
@@ -49,13 +49,13 @@ The [two-hour `450439c` proposal baseline](evidence/v02/proposal-resource-soak-4
49
49
 
50
50
  The integrated executable passes 471 Linux offline tests, formatting, strict source checks and the installed-archive consumer at `9f85acc`. [All four Windows/Linux × Node 22/24 jobs passed for `9f85acc`](evidence/v02/ci-9f85acc.json), including the new HELDOUT profiles, evaluator metadata correction, explicit-thread resource harness, archive and formatting steps. [The `6f9cc15` run](evidence/v02/ci-6f9cc15.json), [the `e0c190b` run](evidence/v02/ci-e0c190b.json), [the `c35f67d` run](evidence/v02/ci-c35f67d.json) and [the earlier `450439c` run](evidence/v02/ci-450439c.json) remain preserved. [Native Windows installed-archive acceptance](evidence/v02/native-proposal-windows-450439c.json) passes on the changed runtime: eight child starts/closes, none left, physical cancellation and caller ownership. Its 107-file installed manifest matches the reviewed archive exactly. Independent Gitleaks scanned 104 commits / 8.58 MB with no findings. The evaluator-only metadata correction passes these source checks and does not change runtime or scoring. Earlier [c107 CI](evidence/v02/ci-c107ddf.json) and [integration evidence](evidence/v02/integration-25c19cd.json) remain preserved. Final release source still needs its own checks.
51
51
 
52
- The frozen runtime used for v4 had all 53 source files and 106 compiled runtime files byte-identical to `0c365cb`. The new box-confirmation development hypothesis changes the proposal process and presenter, so the historical native/resource receipts below do not automatically cover its new bytes. Fresh native Windows acceptance has passed; the new two-thread resource run remains active. The first proposal resource run completed its configured wall-clock phases, but its observed process lifetime and summed monotonic operation durations did not prove the required physical duration. It is retained as historical evidence. Replacement harness `261dc23` uses monotonic phase deadlines, enforces the full duration minima, and has a separate kernel-uptime observer. Its [fresh two-hour run passed](evidence/v02/proposal-resource-soak-261dc23.md): 7,212.6 monotonic seconds, an independent live process-age witness at 7,200.68 seconds, and 2,158 native starts/closes in the measurement window with none left. Idle heap, external and array-buffer growth pass the fixed limits; RSS grew 115.76 MiB, below the 128 MiB threshold. Root independently checked parity of all 55 pinned files. This fixture run establishes resource/lifecycle behavior; its shared-host timing does not qualify model quality or production latency.
52
+ The frozen runtime used for v4 had all 53 source files and 106 compiled runtime files byte-identical to `0c365cb`. The new box-confirmation development hypothesis changes the proposal process and presenter, so the historical native/resource receipts below do not automatically cover its new bytes. Fresh native Windows acceptance has passed; the new two-thread resource run remains active. The first proposal resource run completed its configured wall-clock phases, but its observed process lifetime and summed monotonic operation durations did not prove the required physical duration. It is retained as historical evidence. Replacement harness `261dc23` uses monotonic phase deadlines, enforces the full duration minima, and has a separate kernel-uptime observer. Its [fresh two-hour run passed](https://github.com/zoomplus/zorya-classifier/blob/36818582091bfd19951631f358183bdb9ffd1e11/docs/evidence/v02/proposal-resource-soak-261dc23.md): 7,212.6 monotonic seconds, an independent live process-age witness at 7,200.68 seconds, and 2,158 native starts/closes in the measurement window with none left. Idle heap, external and array-buffer growth pass the fixed limits; RSS grew 115.76 MiB, below the 128 MiB threshold. Root independently checked parity of all 55 pinned files. This fixture run establishes resource/lifecycle behavior; its shared-host timing does not qualify model quality or production latency.
53
53
 
54
54
  The [first frozen blind candidate](evidence/v02/heldout-evaluation-20261020.md) failed: 3/60 positive whole-object boxes matched, there were 2/20 false locations against a limit of one, and the paired photo bootstrap interval was [0, 0.20], whose lower bound must be positive. Four of six scored mask instances reached IoU 0.8; nineteen reference instances were unavailable. Mask and box metrics remain separate. The no-image control completed all 40 photos with no successful location. No alternative is selected from these revealed heldout results.
55
55
 
56
56
  The [six-case split Choice/NoUL pilot](evidence/v02/split-choice-noul-dev6.md) failed its predeclared positive gate: classification 4/6, positive whole-object matches 0/2, false locations 0/4 verified negatives, and one failed localization. The [split categorical-presence follow-up](evidence/v02/categorical-presence-dev6.md) also produced no locations. Neither failed split profile advanced to full DEV40.
57
57
 
58
- The distinct native categorical batch comparison completed both original DEV40 profiles: [preserving the neutral instruction](evidence/v02/categorical-dev40-preserve.json) reached 3/30 positive whole-object matches, while [target alone](evidence/v02/categorical-dev40-target-only.json) reached 0/30. Both classify 35/40 and have zero false locations on ten negatives. Preserving the instruction is [frozen as the development selection](evidence/v02/categorical-vision-method-selection.json), before new heldout pixels or per-case truth were opened. Its eight 502 failures and eight unknown charges remain counted. The second profile has four such failures. Timing is unranked under concurrent native stress; no latency tie-break was needed. This caller-owned recipe does not become a library default or qualify blind accuracy. The new 80-case cohort has independent photo, controlled Mousepad UI and controlled Minetest minimap source oracles. Its [first setup attempt failed before HTTP](evidence/v02/categorical-heldout-predispatch-20261020-v3.json); the separate [v4 freeze](evidence/v02/categorical-heldout-run-freeze-20261020-v4.json) binds the corrected common photo instruction, unchanged images/targets/truth and the exact executable producer closure. Both measurements completed before independent truth evaluation. The [v4 result failed qualification](evidence/v02/categorical-heldout-v4/README.md): 1/60 positive whole-object boxes, zero false locations on 20 negatives, and paired photo bootstrap interval [0, 0.10]. Classification is 69/80, including ten false positives; the no-image control has zero positive locations. All 456 physical calls, seven unknown charges and failures remain counted. The initial mask section has no joined references; the separate official index has 32 masks on 21 photos, with 30 masks using a different full-frame canvas. A separate exploratory normalized-canvas calculation records seven scored reference instances, three at IoU 0.8, and 25 unavailable predictions; exact alignment remains unqualified and cannot change the box/paired failure. These cases are now exposed regression data; a changed method requires new development and a fresh blind cohort.
58
+ The distinct native categorical batch comparison completed both original DEV40 profiles: [preserving the neutral instruction](evidence/v02/categorical-dev40-preserve.json) reached 3/30 positive whole-object matches, while [target alone](evidence/v02/categorical-dev40-target-only.json) reached 0/30. Both classify 35/40 and have zero false locations on ten negatives. Preserving the instruction is [frozen as the development selection](evidence/v02/categorical-vision-method-selection.json), before new heldout pixels or per-case truth were opened. Its eight 502 failures and eight unknown charges remain counted. The second profile has four such failures. Timing is unranked under concurrent native stress; no latency tie-break was needed. This caller-owned recipe does not become a library default or qualify blind accuracy. The new 80-case cohort has independent photo, controlled Mousepad UI and controlled Minetest minimap source oracles. Its [first setup attempt failed before HTTP](evidence/v02/categorical-heldout-predispatch-20261020-v3.json); the separate [v4 freeze](evidence/v02/categorical-heldout-run-freeze-20261020-v4.json) binds the corrected common photo instruction, unchanged images/targets/truth and the exact executable producer closure. Both measurements completed before independent truth evaluation. The [v4 result failed qualification](https://github.com/zoomplus/zorya-classifier/blob/36818582091bfd19951631f358183bdb9ffd1e11/docs/evidence/v02/categorical-heldout-v4/README.md): 1/60 positive whole-object boxes, zero false locations on 20 negatives, and paired photo bootstrap interval [0, 0.10]. Classification is 69/80, including ten false positives; the no-image control has zero positive locations. All 456 physical calls, seven unknown charges and failures remain counted. The initial mask section has no joined references; the separate official index has 32 masks on 21 photos, with 30 masks using a different full-frame canvas. A separate exploratory normalized-canvas calculation records seven scored reference instances, three at IoU 0.8, and 25 unavailable predictions; exact alignment remains unqualified and cannot change the box/paired failure. These cases are now exposed regression data; a changed method requires new development and a fresh blind cohort.
59
59
 
60
60
  The [paired segmentation component comparison](evidence/v02/segmentation/component-comparison-summary.json) uses the same five public DEV photos and independent masks for both MobileSAM and GrabCut. Its corrected, oracle-assisted seed panel gives mean per-case mask IoU 0.859 versus 0.595; its 53-file runtime snapshot matches `c107ddf`, before the two later proposal prompt/presentation changes. The native backend implementations are unchanged. This supports a component comparison under supplied geometry, not end-to-end accuracy or a library-selected backend.
61
61
 
@@ -95,7 +95,7 @@ The release is **not qualified or published yet**. The following table and parag
95
95
 
96
96
  Whole-object location, explicit extraction, optional native adapters and CLI are implemented and integrated. [Snapshot evidence](evidence/v02/integration-8010aad.json) records source commit, actual installed-archive hash and check results. The 254-test snapshot passed source gates and the independent consumer tested the old and new APIs with zero provider HTTP calls. Subsequent diagnostic/corpus integration passed 256 tests; these counts are offline evidence, not model accuracy.
97
97
 
98
- The installed consumer imports core and segmentation entries and compiles declarations without ONNX Runtime. It exercises cutout/mask output with a controlled segmenter and proves caller ownership. The [native CPU smoke](../benchmarks/v02/native-smoke-evidence.md) separately exercised real MobileSAM on five licensed dev photographs with independent instance masks. These are distinct tests.
98
+ The installed consumer imports core and segmentation entries and compiles declarations without ONNX Runtime. It exercises cutout/mask output with a controlled segmenter and proves caller ownership. The [native CPU smoke](https://github.com/zoomplus/zorya-classifier/blob/main/benchmarks/v02/native-smoke-evidence.md) separately exercised real MobileSAM on five licensed dev photographs with independent instance masks. These are distinct tests.
99
99
 
100
100
  The configured two-hour Linux CPU resource run completed against the frozen native sources of `8010aad`: ten minutes of warmup followed by two idle windows and the 6,540-second busy phase. Its [numeric report](evidence/v02/resource-soak-linux-8010aad.json) records 4,756 segmented operations, matching child starts/closes and no owned children left. Before/after idle-median growth was approximately 7.4 MiB heap, 11.2 MiB external, 6.2 MiB array buffers and 43.8 MiB RSS, within the plan's thresholds. Sampling was scheduled every five seconds; actual gaps are recorded. Native Windows CPU component acceptance passed against the pinned installed archive: imports/declarations, real inference, cancellation, queue capacity and disposal left zero owned children. The [hardened report](evidence/v02/native-windows-eea1790.json) separates those lifecycle checks from mask quality. These tests use oracle boxes, not end-to-end localization. Live whole-object qualification and the experimental encoder's independent development/heldout gates remain pending. Historical 0.1 results below do not qualify these additions.
101
101
 
@@ -105,7 +105,7 @@ The subsequent [CI run for `9d00fe5`](evidence/v02/ci-9d00fe5.json) passed all f
105
105
 
106
106
  All six text-image encoders remain research-only. The [fresh independent comparison](evidence/v02/fresh-text/README.md) is complete for photographs and real UI: every encoder has zero correct whole-object matches, and some violate the negative-case gate. None qualifies for heldout promotion. The initial classification harness defect and corrected classification-only follow-ups are preserved separately; they do not overwrite the localization runs. Failed protocol/rate-limit/truncated-generation diagnostics remain recorded. The public experimental image selector rejects explicitly. Historical controlled map/UI renders with model-assisted labels remain an exploratory supplement: their source licensing and split are recorded, but they do not close the independent-ground-truth gate.
107
107
 
108
- Subsequent [whole-object prompt/presentation experiments](evidence/v02/boundary-variants.md) found one correctly bounded Car example after removing the separate seed crop and outlining that seed on the original. Boat still returned unknown; this is development evidence, not qualification. A [controlled real-UI oracle](../benchmarks/v02/corpus/dev-independent-ui/README.md) now independently derives seven button boxes from GTK accessibility allocations and verifies all painted edges in the captured pixels. Its three negatives are scoped to the completely inventoried visible toolbar. It is one controlled source family, not a diverse natural-UI benchmark.
108
+ Subsequent [whole-object prompt/presentation experiments](evidence/v02/boundary-variants.md) found one correctly bounded Car example after removing the separate seed crop and outlining that seed on the original. Boat still returned unknown; this is development evidence, not qualification. A [controlled real-UI oracle](https://github.com/zoomplus/zorya-classifier/blob/main/benchmarks/v02/corpus/dev-independent-ui/README.md) now independently derives seven button boxes from GTK accessibility allocations and verifies all painted edges in the captured pixels. Its three negatives are scoped to the completely inventoried visible toolbar. It is one controlled source family, not a diverse natural-UI benchmark.
109
109
 
110
110
  The five-photo native reports also retain a subsequently discovered fixture limitation: the original Hat seed contains zero ground-truth foreground pixels, and the Cat seed center is background. Their historical results are preserved. These invalid or ambiguous grounding prompts must not be interpreted as a clean segmentation-quality comparison; corrected oracle prompts require a separate manifest and report. This does not change the physical lifecycle/resource scope of the original run.
111
111
 
@@ -0,0 +1,95 @@
1
+ # Правила для агентов (Zorya Classifier)
2
+
3
+ Независимая MIT-библиотека. Технический контракт на английском: [AGENTS.md](https://github.com/zoomplus/zorya-classifier/blob/main/AGENTS.md). Архитектура и разработка: [архитектура](architecture.ru.md), [разработка](development.ru.md). Статус волн: [план рефакторинга](refactoring-plan.ru.md).
4
+
5
+ ## Глобальные правила владельца
6
+
7
+ Cursor **не** подгружает автоматически файлы из `/root/.cursor/rules/`. **Главный оркестратор** и **каждый** порождённый подагент Codex должны прочитать оба канонических файла:
8
+
9
+ | Файл | Назначение |
10
+ | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
11
+ | `repository-cleanliness.mdc` (`/root/.cursor/rules/repository-cleanliness.mdc`) | Уборка только артефактов текущей задачи; сохранять чужие ветки, блокировки и журналы проверок |
12
+ | `context7.mdc` (`/root/.cursor/rules/context7.mdc`) | Внешняя документация SDK, API и CLI по запросу; **не** для внутреннего рефакторинга и документации репозитория |
13
+
14
+ **Координатор** **включает** применимые пункты глобальных правил и [контракт участников](https://github.com/zoomplus/zorya-classifier/blob/main/AGENTS.md) в текст каждой задачи для исполнителя Composer. Не дублировать глобальные правила в [правила проекта](https://github.com/zoomplus/zorya-classifier/blob/main/.cursor/rules/zorya-classifier.mdc).
15
+
16
+ ## Роли
17
+
18
+ | Роль | Модель / исполнитель | Обязанности |
19
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20
+ | **Главный оркестратор** | Выбирает **человек** (нет модели главного по умолчанию) | По умолчанию: анализ, исследование, проверка изменений, планирование, прогон тестов, интеграция в Git после проверки; **никогда** не запускает и не владеет Cursor CLI; **не** подменяет Composer при правках исходников, тестов и документации в разрешённых границах |
21
+ | **Координатор** | **`gpt-6-luna`**, рассуждение **`high`**, **`fork_turns=none`** (иначе — только явная инструкция человека) | Владелец **каждого** процесса Cursor CLI; предварительная проверка CLI перед первым запуском; постановка задач Composer; проверка фактических изменений и журналов; передача владения — только явно |
22
+ | **Исполнитель Composer** | **`composer-2.5-fast`** | Редактирует разрешённые пути **сам**; **не** запускает `cursor-agent`, не делегирует и не запускает вложенных агентов |
23
+
24
+ **Каждый** подагент Codex любой роли (включая координацию и явно запрошенные исследование или проверку изменений) порождается как **`gpt-6-luna` / `high` / `fork_turns=none`**, если человек не указал иное.
25
+
26
+ Отдельные подагенты для исследования или проверки изменений — **только по явному запросу** человека и остаются **только для чтения**. Иначе исследование и проверку изменений выполняет главный оркестратор.
27
+
28
+ Координатор **не обязан** работать в том же OS-процессе, что и главный оркестратор; важно явное владение процессом Cursor и передача владения.
29
+
30
+ ## Видимость плана (не повторное согласование)
31
+
32
+ Перед **любым** запуском реализации или перепланированием главный оркестратор **показывает пользователю** нумерованные волны в порядке зависимостей. Для каждой волны: роли (главный / координатор / Composer), идентификаторы моделей и `fork_turns`, конкретные пути в зоне ответственности, входы и предварительные условия, параллелизм (не более 3 процессов Composer глобально, отдельные рабочие деревья Git при параллели), артефакты (журналы в **корне артефактов вне репозитория**), проверки и критерии выхода; рядом — краткое русское «зачем».
33
+
34
+ Уже данной в сессии авторизации достаточно для реализации, проверки изменений, исправлений, тестов и интеграции в разрешённых границах — не изобретать повторные циклы согласования. При реальной нехватке модели, доступа, аутентификации или квоты — сообщить фактически, **без** подстановки другой модели или режима Auto.
35
+
36
+ Проверка изменений опирается на **фактические изменения в файлах и вывод тестов**, а не на пересказ модели.
37
+
38
+ ## Запуск Composer (координатор)
39
+
40
+ Перед **первым** запуском:
41
+
42
+ ```sh
43
+ cursor-agent --version
44
+ cursor-agent status
45
+ cursor-agent models
46
+ ```
47
+
48
+ Запуск **только** с моделью **`composer-2.5-fast`**. Запрещены Auto и скрытая подстановка `composer-2.5` или других семейств — остановиться и сообщить блокер.
49
+
50
+ **Один координатор на один процесс Cursor.** Глобально **не более 3** процессов Composer. Параллель: отдельные **рабочие деревья Git**, непересекающееся владение файлами; слияние после проверки изменений и тестов; общие файлы — явная координация.
51
+
52
+ Пример из корня репозитория (без секретов в тексте задачи):
53
+
54
+ ```sh
55
+ cursor-agent \
56
+ --workspace "$PWD" \
57
+ --print \
58
+ --force \
59
+ --output-format stream-json \
60
+ --model composer-2.5-fast \
61
+ "…текст задачи: пути в зоне ответственности, ограничения, запрет рекурсивного запуска agent…"
62
+ ```
63
+
64
+ ## Инварианты кода (кратко)
65
+
66
+ Слои: [архитектура](architecture.ru.md), `npm run boundaries`.
67
+
68
+ - Строгий TypeScript и Zod на границах; без подстановки провайдера.
69
+ - Байты входа — до первого `await`; один абсолютный предельный срок с очередью; слоты до фактического завершения работы; `dispose` дожидается завершения.
70
+ - v0.2 `extract`: геометрия из маски, закрытая проверка рамки, не более одного расширения маски и финальной проверки; без координат от модели.
71
+ - Ранг не равен вероятности; один финальный ID против четырёх кандидатов пространственной стадии луча.
72
+ - Каталог `benchmarks`: `hashCanonical` = `SHA-256`(`JSON.stringify`) с фиксированным порядком полей.
73
+ - Исследования в `benchmarks/experiments/` — вне дистрибутива npm; публичный профиль `experimental-text` явно отклоняет не квалифицированные запросы.
74
+
75
+ ## Тесты
76
+
77
+ | Набор | Команда |
78
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------- |
79
+ | Переносимый каталог | `npm test` |
80
+ | Локальные свидетельства | `npm run test:local-evidence` (H5, `grounded-mask`, минимальный H10 — см. [разработку](development.ru.md)) |
81
+ | Группа `python-native` | `npm run test:python-native` (см. [разработку](development.ru.md)) |
82
+
83
+ Единый раннер: `scripts/run-classified-tests.mjs`. Не ссылаться на удалённый `run-portable-tests.mjs`.
84
+
85
+ Измеренные счётчики переносимого каталога и платформы — [план рефакторинга](refactoring-plan.ru.md). На измеренном Linux-хосте Python **3.12.3**: установлены `PIL`/`Pillow`; **`numpy`**, **`torch`** и **`transformers`** **отсутствуют**; набор `python-native` **не запускался**. Переносимый каталог: **772** успешных, **0** пропущенных (необязательные тесты без ресурсов могут пропускаться). Узкие проверки исполнителя Composer под встроенным Linux Node 24 **не** равны полным проверкам главного оркестратора на Node 24.
86
+
87
+ ## Секреты, платные прогоны, публикация
88
+
89
+ `npm run secrets:check`, сканирование **версий файлов, добавленных в индекс Git** (Husky), `npm run pack:check`. Ключ каталога `benchmarks`: `OPENROUTER_API_KEY` или явный `--env-file` **только** в `run-region-seeded-dev.ts` / `run-quality-pilot.ts` — [разработку](development.ru.md).
90
+
91
+ Не коммитить `.env`, частные медиа, журналы чатов. Платные прогоны, GPU и публикация — явная область работ и бюджеты.
92
+
93
+ ## Уборка
94
+
95
+ Только рабочие деревья, временные каталоги и кэш, созданные текущей задачей. Сохранять ранее существующие изменения, неудачные журналы проверок (артефакты **вне** репозитория), посторонние ветки. См. `repository-cleanliness.mdc`.
package/docs/api.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Public API
2
2
 
3
+ Spatial localization, whole-object location, extraction, `RefinementPort`, caller-owned segmentation/box-check composition, `objectProposals`, and native segmentation factories are **experimental and unqualified** for general use (TypeScript `@experimental` on the corresponding public types and methods). Closed `classify` and explicitly configured `DecisionPort`/transport adapters remain supported; they do not imply universal model accuracy. Further spatial accuracy experiments are stopped; no strategy is promoted.
4
+
3
5
  `createClassifier({ decision, timeoutMs?, concurrency?, maxQueue?, maxInputBytes?, refinement?, segmentation?, objectProposals? })` creates an owned client. Defaults: 45,000ms absolute budget including queue/image work/provider work; two active operations; sixteen waiters; 64 MiB total admitted input bytes, reserved before copying. Configured maxima: 120s, four active,32 queued,256 MiB admitted input. Input images are at most16MiB and16,777,216 decoded pixels, with source sides at most16,384; single PNG/JPEG/WebP only. The vision adapter accepts prepared PNG/JPEG with sides280..1568 and a32MiB total request cap. Byte inputs are copied before the first await, including Buffer views.
4
6
 
5
7
  The caller supplies the `DecisionPort`; the library never chooses a model, provider or endpoint. You may inject a port directly or explicitly construct one of the adapters below. Their model/provider values are examples or benchmark recipes, not defaults, and stronger models do not guarantee higher accuracy. Optional segmentation adapters are configured separately and require caller-installed runtime packages and caller-supplied local assets.
@@ -8,13 +10,13 @@ The [0.2 guide](v02-usage.md) documents `extract`, mask-derived `locate({ mode:
8
10
 
9
11
  `classify({ input, classes, instructions?, signal? })`: input is a string or `{ text?, image? }` with at least one field. Classes are2..255 distinct IDs plus descriptions. IDs match `[a-zA-Z][a-zA-Z0-9_-]*`; descriptions at most300 chars. Text is at most32,000 chars, custom instructions4,000. Define explicit none/other behavior in your classes. With ordinary vision models the result contains `choice` (first ranked ID), `ranking`, `probabilities: null`, `nativeChoice: null`, empty `tied`, and metadata. No rank is converted to a fabricated probability. Optional native integrations instead retain raw probabilities, stable maximum/ties, native choice/confidence and optional quantization annotation. Confidence is never a calibrated spatial guarantee.
10
12
 
11
- `locate({ image, target, exclusions?, roi?, signal? })`: target at most2,000 chars; up to16 exclusions of500 chars. ROI uses integer `left/top/width/height` in EXIF-oriented source pixels. Return coordinates reference that oriented image; metadata names this space and dimensions. Rectangles include left/top and exclude right/bottom. Normalized rectangle fields are divided by image dimensions. Tiny/impossible bounded grids return `unknown/layout-limit`.
13
+ `locate({ image, target, exclusions?, roi?, signal? })` (**experimental**): target at most2,000 chars; up to16 exclusions of500 chars. ROI uses integer `left/top/width/height` in EXIF-oriented source pixels. Return coordinates reference that oriented image; metadata names this space and dimensions. Rectangles include left/top and exclude right/bottom. Normalized rectangle fields are divided by image dimensions. Tiny/impossible bounded grids return `unknown/layout-limit`.
12
14
 
13
15
  `located` from default region mode returns a selected grid region, normalized region, third-stage selection evidence and optional refinement. `not-found/absent-in-evaluated-region` is based on the initial independent presence check. A target missing from later shortlisted cells yields `unknown/candidate-union-empty`, not global absence. Ordinary models return present/absent/unknown as an independent categorical predicate. Legacy Noul0.5 abstains; contradictory presence/selection returns unknown. Multiple physical matching objects are permitted; this is an any-instance locator. With an explicit `segmentation` port, `locate({ mode: 'whole-object' })` and `extract` use the region seed plus full-source segmentation; reported bounds and center come from the valid mask.
14
16
 
15
17
  The algorithm searches4×4 coarse cells, keeps four source-distinct maxima, pads each by half a coarse cell within ROI, partitions each into at most49 fine cells (global≤196, side≤256), then compares the four best fine cells as enlarged A–D/none. Edges count as matches. Scores/rank hints are not sent to the final comparison. No cell-center correction is presented as object segmentation.
16
18
 
17
- `RefinementPort.refine({ image, target, region, signal })` is optional trusted code. It receives a private oriented-source byte copy. A returned refined rectangle must fit the source and intersect the selected cell. It does not replace the original area evidence. No built-in heavy refiner is downloaded.
19
+ `RefinementPort.refine({ image, target, region, signal })` (**experimental**) is optional trusted code. It receives a private oriented-source byte copy. A returned refined rectangle must fit the source and intersect the selected cell. It does not replace the original area evidence. No built-in heavy refiner is downloaded.
18
20
 
19
21
  `dispose()` cancels current/queued work, rejects further calls and waits for physical settlement. Injected ports must honor cancellation. Native image work retains its concurrency slot until completion, even if cancellation has already been requested.
20
22
 
@@ -1,11 +1,37 @@
1
1
  # Architecture and lifecycle
2
2
 
3
- The public factory composes the caller-supplied `DecisionPort` and a Sharp-backed `RasterPort`. The library does not select a model, provider or endpoint; applications either inject an existing port or explicitly build one with a supported adapter. Processes orchestrate classify/locate; features contain pure Choice interpretation, grid geometry and prompt construction; entities define validated public contracts; infrastructure owns provider HTTP and image processing. No application runtime, game-state schema or workspace import is required.
3
+ Russian guide with layer map, SOLID notes and current paths: [architecture.ru.md](architecture.ru.md). Development onboarding: [development.ru.md](development.ru.md).
4
+
5
+ Closed `classify` and injected `DecisionPort`/adapter transport are supported integration paths. Region `locate`, whole-object location, extraction, `RefinementPort`, caller-owned segmentation and box-check composition, `ObjectProposalPort`, and explicit native segmentation factories are experimental and unqualified; they are labeled `@experimental` on the public API. No spatial or extraction strategy is promoted; evidence under `docs/evidence/**` remains historical.
6
+
7
+ The public factory composes the caller-supplied `DecisionPort` and a Sharp-backed `RasterPort`. The library exposes four package entries (`.`, `./openrouter`, `./openai-compatible`, `./segmentation`); the CLI is a separate bin, not a fifth library export. The library does not select a model, provider or endpoint; applications either inject an existing port or explicitly build one with a supported adapter. **Import layers:** `app` composes `processes` and `infrastructure`; `processes` depend on `features`, `entities`, and `shared` port contracts only (no direct `processes` → `infrastructure` imports); `infrastructure` implements ports and may use `features`/`entities`/`shared`. Runtime calls reach HTTP, raster, and native work through injected port instances wired in `app`. Processes orchestrate classify/locate; features contain pure Choice interpretation, grid geometry and prompt construction; entities define validated public contracts. Benchmark runners live under `benchmarks/v02/`, `benchmarks/v03/`, and the repo root as well as helpers in `benchmarks/experiments/`; not all runners are under `experiments/`. No application runtime, game-state schema or workspace import is required.
4
8
 
5
9
  The primary 0.2 object path preserves the original region locator. Its selected seed prompts an explicitly configured segmenter on the full oriented source image; actual mask pixels determine bounds, center and the optional cutout. A generic closed containment checker receives the full source with the mask-derived box and original seed anchor. It uses the injected decision port and a presentation port; the process allows at most one actual enclosing-mask correction and a final check. The segmenter can implement optional `expand`; corrected foreground must strictly contain the old visible foreground and grow the real box within the hard ROI. The process rejects unresolved checks without publishing a partial cutout. Its absolute deadline, cancellation and byte ownership cover every stage. No additional extent search or model-generated coordinates are used. `locate({ mode: 'whole-object' })` and `extract` use the same mask-derived geometry when a segmenter is configured. Boundary-interval location and `ObjectProposalPort` remain optional legacy strategies with their own request flows.
6
10
 
7
11
  Extraction composes the selected locator with a caller-owned `SegmentationPort` and a `CutoutRasterPort`; processes import neither Sharp nor native inference. Explicitly created native adapters own their workers and queues, while the caller supplies and manages their optional runtime packages and local model assets. No weights are selected, installed or downloaded by the library. [Operation and ownership details](v02-usage.md) are explicit; no experimental text-image profile is publicly qualified yet.
8
12
 
13
+ ```mermaid
14
+ flowchart TB
15
+ subgraph appLayer [app]
16
+ APP[create-classifier]
17
+ end
18
+ subgraph procLayer [processes]
19
+ PROC[classify / locate / extract]
20
+ end
21
+ subgraph featLayer [features + entities + shared]
22
+ FEAT[choice / grid / contracts / gate]
23
+ end
24
+ subgraph infraLayer [infrastructure]
25
+ INF[decision-transport / raster / native segmentation]
26
+ end
27
+ APP --> PROC
28
+ APP --> INF
29
+ PROC --> FEAT
30
+ INF --> FEAT
31
+ ```
32
+
33
+ Runtime orchestration (same primary extract semantics as below):
34
+
9
35
  ```mermaid
10
36
  flowchart LR
11
37
  I[Owned input snapshot] --> G[Bounded operation queue]
@@ -14,12 +40,14 @@ flowchart LR
14
40
  L --> S[Caller-owned segmenter on full source with seed prompt]
15
41
  S --> M[Validate mask and derive visible bounds / center]
16
42
  M --> B[Closed box check on full source and seed anchor]
17
- B -->|complete| X[Optional transparent cutout]
43
+ B -->|complete| X[Result / optional transparent cutout]
18
44
  B -->|unknown| U[Explicit unresolved result]
19
- B -->|needs expansion| E[At most one actual enclosing-mask correction]
20
- E --> R[Validate foreground containment and recheck actual box]
45
+ B -->|needs-expansion| E[At most one actual enclosing-mask correction]
46
+ E -->|success| P[Preserve every prior visible foreground pixel]
47
+ E -->|no expand / no valid enclosing mask| U
48
+ P --> R[Final check on actual box]
21
49
  R -->|complete| X
22
- R -->|unresolved / no parent| U
50
+ R -->|unknown / needs-expansion| U
23
51
  ```
24
52
 
25
53
  One deadline covers the whole operation, including queue time. AbortSignal passes through every boundary; guards after awaits reject late results. Physical Sharp/provider work retains its slot until its promise settles. Timers/listeners are cleared in finally. There is no import-time worker, automatic retry, persistent image cache, database or background polling loop.