# Исследования SQL: активность расширений

Статус: `in_progress`. Этот журнал отделяет наблюдения от гипотез. Ничего из
раздела «гипотеза» не используется адаптером как runtime-правило.

## 2026-08-02 — baseline `upo_test`

Цель: установить доказанный SQL-признак флажка «Активно» расширения в
Конфигураторе.

Снимок выполнен только чтением из `dbo._ExtensionsInfo` для имён
`фс_Отчеты` и `фс_Отчеты1`. Зафиксированы все известные скалярные поля строки
и SHA1 `_ExtensionZippedInfo`; бинарные данные и учётные сведения не сохранены.

| name | `_IDRRef` (hex) | `_ExtensionOrder` | `_UpdateTime` | `_ExtensionUsePurpose` | `_ExtensionScope` | zipped bytes | zipped SHA1 |
| --- | --- | ---: | --- | ---: | ---: | ---: | --- |
| `фс_Отчеты` | `0x8287005056B0D48311F13D089B11F844` | 21 | 4026-05-07 23:45:25 | 2 | 1 | 188 | `0D07CB6CE05AADB301A002CAB7312AD6EA64A344` |
| `фс_Отчеты1` | *строка отсутствует* | — | — | — | — | — | — |

### Подтверждено

- Наличие строки в `_ExtensionsInfo` доказывает регистрацию расширения в
  данном SQL-снимке, но **не** доказывает флажок «Активно» в Конфигураторе.
- Поэтому поле `active` адаптера для такого источника возвращается как
  `null`; прежнее значение `true` было неподтверждённым и удалено.

### Гипотеза, требующая проверки

После переключения флажков в Конфигураторе изменится одна или несколько
наблюдаемых SQL-структур: строка `_ExtensionsInfo`, поля строки, DBNames-Ext,
ConfigCAS/ConfigCASSave или иной live SQL-маркер.

### Следующий контролируемый опыт

1. Пользователь активирует `фс_Отчеты` и выключает `фс_Отчеты1` (либо наоборот)
   в Конфигураторе и сообщает, когда действие сохранено.
2. Адаптер снимает тот же снимок `_ExtensionsInfo` и дополнительно сравнивает
   только подтверждённые live SQL-маркеры.
3. Правило будет добавлено в runtime лишь если различие воспроизводится при
   обратном переключении и однозначно связано с активной композицией.

### Запрещённый вывод до опыта

Нельзя отбрасывать расширение из поиска только по факту его наличия или
отсутствия в `_ExtensionsInfo`, по совпадающему GUID объекта либо по догадке
из названия/порядка расширения.

## 2026-08-02 — baseline `upo` (текущий опыт)

Этот снимок является исходной точкой для переключения, которое пользователь
будет выполнять в `upo`. Он не смешивается с наблюдением `upo_test` выше.

| name | `_IDRRef` (hex) | GUID из `_IDRRef` | `_ExtensionOrder` | `_UpdateTime` | `_ExtensionUsePurpose` | `_ExtensionScope` | zipped bytes | zipped SHA1 |
| --- | --- | --- | ---: | --- | ---: | ---: | ---: | --- |
| `фс_Отчеты` | `0xA0CF005056B59ABC11F13D592F0651F1` | `2f0651f1-3d59-11f1-a0cf-005056b59abc` | 20 | 2001-01-01 00:00:00 | 2 | 1 | 188 | `2718A3CC564F593799EFCF1E716305358AF804E8` |
| `фс_Отчеты1` | `0x8294005056B0D48311F18A348E02ACCD` | `8e02accd-8a34-11f1-8294-005056b0d483` | 22 | 4026-08-01 18:51:55 | 2 | 1 | 188 | `A9A4AF42BBA2084141A122F9D7C39D7E1428CB21` |

На baseline присутствуют обе строки. Значит наличие в `_ExtensionsInfo` не
может быть критерием активности: оно не отличает выключенное `фс_Отчеты` от
включенного `фс_Отчеты1` на скриншоте пользователя.

## 2026-08-02 — подтверждённый декодер активности

Три независимых переключения флажка в Конфигураторе, сохранённые пользователем
в `upo`, дали один и тот же результат. Не весь SHA1, а **третий байт с конца**
`_ExtensionZippedInfo` меняется вместе с флажком:

| расширение | длина контейнера | состояние в UI | третий байт с конца |
| --- | ---: | --- | --- |
| `фс_Отчеты` | 188 | выключено → включено | `81` → `82` |
| `фс_Отчеты1` | 188 | включено → выключено | `82` → `81` |
| `ЭкстракторДанных1СВBI` | 215 | включено → выключено | `82` → `81` |

Другие изменения контейнера не являются маркером: например, байт около начала
контейнера и весь SHA1 меняются при сохранении Конфигуратором.

### Runtime-правило (подтверждено для наблюдаемой версии)

`SUBSTRING(_ExtensionZippedInfo, DATALENGTH(_ExtensionZippedInfo) - 2, 1)`:

- `0x82` — расширение активно;
- `0x81` — расширение выключено;
- любое иное значение — `active: null`, `unresolved`.

Правило декодирует только активность и не интерпретирует остальные байты
контейнера. Перед использованием для фильтрации глобального поиска требуется
отдельный regression-тест, что выключенная extension route не попадает в
`effective_working` code search/read.

## 2026-08-02 — расширенная матрица флажков

В Конфигураторе была показана полная таблица расширений с дополнительными
флажками: безопасный режим, защита от опасных действий, использование в
распределённой ИБ и «использовать основной режим». Их комбинации различаются
между активными расширениями. Повторный read-only снимок `upo` дал:

- 14 расширений с UI-флажком «Активно» получили завершающий байт `82`;
- `ЭкстракторДанных1СВBI` и `фс_Отчеты1` с выключенным «Активно» получили
  `81`;
- среди активных строк есть разные состояния каждого показанного
  дополнительного флажка, но их завершающий байт всё равно `82`.

### Уточнённый вывод

`81` и `82` надо рассматривать как два **наблюдаемых кода состояния
активности** в третьем байте с конца, а не как полную структуру битовых
флажков расширения. Технически это может быть битовое поле, перечисление или
маркер внутри более крупного протокола — формат этого байта пока не доказан.
Для runtime достаточно точного соответствия `81`/`82`; никаких выводов о
других флажках из него делать нельзя.

### Принятое правило адаптера

Рабочая композиция адаптера содержит только строки с `active: true` (`82`).
По умолчанию неактивные и нераспознанные расширения:

- не выдаются методом `extensions.list`;
- не участвуют в DBNames-Ext, ConfigCAS, manifest и cache-маршрутах;
- не участвуют в глобальном поиске модулей и объектов;
- не могут стать целью чтения или записи.

Явная попытка обратиться к известному выключенному расширению завершается
`status: unavailable`, `error: extension_inactive`; адаптер не читает и не
строит маршрут к его объектам. Это исключает неоднозначность одинакового GUID
объекта в активном и выключенном расширениях.

Это правило распространяется и на технические селекторы: верхнеуровневый
`extension_guid`, а также публичный `ConfigCASSave` file route с префиксом
GUID. Публичное чтение `ConfigCAS` разрешено только для ключа, который
подтверждён манифестом активного расширения; непринадлежащий активной
композиции файл получает `extension_route_not_active`. Внутренние SQL-вызовы
адаптера отделены от этого публичного барьера, чтобы он мог доказуемо
построить маршрут, но не раскрывает эти строки агенту.

### Неподтверждённая гипотеза

Остальные флажки записаны в других позициях `_ExtensionZippedInfo` либо в
другой SQL-структуре. Это не используется адаптером.

### Следующий опыт для декодирования остальных флажков (только по необходимости)

На одном выбранном расширении оставить «Активно» неизменным и переключить
ровно один другой флажок, сохранить, затем снять бинарный diff. Повторить
обратное переключение. До двухстороннего воспроизведения позиция и смысл
изменившихся байтов остаются гипотезой.

## Неподтверждённое направление — opaque `module_ref`

Нельзя отбрасывать любой `ConfigCAS`/`ConfigCASSave` `module_ref` только по
имени физического файла: у части подтверждённых активных модулей GUID
расширения отсутствует в имени и восстанавливается только из доказанного
контекста владельца. Ранняя фильтрация такого `module_ref` была проверена и
отменена, так как блокировала активные маршруты. Дальнейшее усиление возможно
только после доказанного owner-resolution до чтения модуля; до этого нельзя
объявлять opaque module_ref маршрутом выключенного расширения или менять его
семантику догадкой.

### Подтверждённое частное правило для `module_ref`

Если physical `ConfigCASSave module_ref` содержит стандартный префикс
`<extension-guid>__`, GUID слоя доказуем до чтения контейнера. Адаптер
проверяет этот GUID по активной композиции и возвращает `extension_inactive`
для выключенного расширения. Это правило не распространяется на непрозрачные
имена файлов без GUID: для них по-прежнему требуется доказательство владельца.
