Репозиторій — це не просто «проєкт». Він щось будує, і саме те, що він будує, визначає, яких практик від нього розумно очікувати. Від опублікованої бібліотеки очікується, що вона не коммітитиме файл блокування залежностей: зафіксовані нею версії однаково проігнорує кожен, хто її встановлює. Від застосунку поруч із нею в каталозі очікується протилежне, бо зафіксовані ним версії — це рівно те, що потрапляє в розгортання. Судити обох за одним правилом означає хибно прочитати одного з них.
До метрик 2.3.0 це питання заміняв єдиний проксі-сигнал: чи публікує репозиторій пакет у реєстрі. За ним кожен інструмент командного рядка на PyPI читається як бібліотека, а кожен застосунок, що принагідно випускає один допоміжний пакет, — так само.
Усі прочитання, які підтверджує доказова база
Класифікація є мультилейбловою. Програмне забезпечення, що є водночас опублікованою бібліотекою і запускним інструментом, — звичайний випадок, а не суперечність, яку треба розв'язати: ripgrep є і крейтом, і бінарником, esbuild є і npm-пакетом, і виконуваним файлом. Тому репозиторій зберігає всі прочитання, які підтверджує його доказова база.
Словник — дворівневе дерево. Верхній рівень відповідає на питання, яке має значення, — як споживається програмне забезпечення, — і репозиторій може нести більш ніж одну гілку:
| Верхній рівень | Що робить обґрунтованим очікувати |
|---|---|
| Бібліотека — споживається як код | Стабільний інтерфейс, журнал змін, версіонування, на яке може спиратися інше ПЗ |
| Застосунок — запускається як програма | Зафіксовані залежності, гігієна розгортання й конфігурації |
| Розширення хоста — встановлюється в хост | Хост задає модель довіри й ритм випусків |
| Обчислювальний нотатник | Нічого з переліченого — його читає й запускає людина, його ніщо не імпортує і нікуди не встановлює |
Там, де застосовні обидва, застосовні обидва: гібрид несе зобов'язання кожного свого прочитання, а не найм'якшого з них.
Підтипи
Підтипи існують лише там, де точніша відповідь змінює те, чого читачеві варто очікувати: модальність інтерфейсу застосунку або клас хоста, від якого розширення успадковує поверхню довіри.
| Застосунок | Розширення хоста |
|---|---|
| Інструмент командного рядка | Плагін |
| Термінальний інтерфейс | Браузерне розширення |
| Десктопний | Редакторське розширення |
| Мобільний | Тема оформлення |
| Вебінтерфейс | |
| Мережевий сервіс | |
| Чат-бот | |
| MCP-сервер |
Бібліотека навмисно не має підтипів. Попередні редакції розрізняли фреймворк, SDK, клієнт API, проміжне ПЗ і драйвер — а цих меж не існує: axios є клієнтом API і бібліотекою, flask є фреймворком і бібліотекою — питання без правильної відповіді. Те, з чим бібліотека з'єднується, фіксується в іншому місці, як факт інтеграції, а не тут.
Відповідь може зупинитися на верхньому рівні. Бінарна ціль Cargo і розкладка cmd/ у Go доводять, що репозиторій будує виконуваний файл, — але не те, чи це інструмент командного рядка, чи сервер. Такий репозиторій класифікується просто як Застосунок і отримує підтип лише тоді, коли для нього є власні докази. Загальна відповідь, підтверджена доказами, краща за конкретну, яка була б здогадом.
Як отримано відповідь
Свідчення впорядковані за мірою довіри, і жоден окремий слабкий сигнал не дає лейбла.
| Свідчення | Приклади | Вага |
|---|---|---|
| Оголошено у збірковому маніфесті | запис bin у npm, точка входу console_scripts, <OutputType>Exe</OutputType>, type у Composer, <packaging> у Maven, ціль [lib] у Cargo | Вирішальна |
| Оголошено реєстром | тип Packagist, тип пакета NuGet, категорія crates.io | Сильна |
| Оголошені залежності | вебфреймворк, парсер аргументів CLI, клієнт чат-платформи | Помірна |
| Структура дерева файлів | cmd/…/main.go, src-tauri/, чарт Helm, маніфест браузерного розширення | Допоміжна |
| Теми репозиторію та ключові слова реєстру | cli, wordpress-plugin, self-hosted | Слабка — самопризначена |
| Опис репозиторію | «a CLI for…», «a library for…» | Слабка — самопризначена |
Перші два — найсильніші, бо не є думкою: той, хто пише <OutputType>Exe</OutputType>, не описує програму — інакше збірка просто не працювала б. Тема є думкою, і згода двох тем — це мінімум, який узагалі щось несе.
Свідчення діють і у зворотний бік. Cargo-пакет із publish = false, Composer із type project, інструмент .NET, war у Maven — кожне з них виключає належність до того, на що може спиратися інше ПЗ, хоч би як виглядав репозиторій в іншому.
Коли відповіді немає
Три ситуації не дають класифікації, і всі три звичайні:
- Звіт передує класифікації. Кожен збережений звіт було перекласифіковано з фактів, які він уже містив, але свідчення з маніфестів збираються під час сканування, тож зібрані раніше звіти несуть лише слабші рівні й отримають повне прочитання при наступній інспекції репозиторію.
- Доказова база не відповідає на питання. Багато репозиторіїв не публікують маніфестів, не мають інформативних тем і описують себе прозою, яка не стверджує нічого структурного.
- Відповідь була б здогадом. Там, де сигнали є, але надто слабкі, щоб перетнути поріг, не стверджується нічого.
У всіх трьох випадках звіт просто не показує класифікації. Відсутність ніколи не подається як висновок, на ній нічого не оцінюється, і репозиторій без неї не позначається, не понижується в рейтингу й не штрафується жодним чином.
Репозиторії, що будують кілька речей
Монорепо, у якому поруч живуть придатний до розгортання сервіс і три опубліковані бібліотеки, не є одним артефактом, і згортання його до єдиної відповіді втратило б той факт, що істинні обидва прочитання. Тому кожен маніфест класифікується за власними деклараціями, а репозиторій несе об'єднання.
Один наслідок варто назвати прямо: єдиний головний лейбл, показаний для такого репозиторію, — це найкраще підтверджений, а у великому монорепо ним може виявитися опублікований збірковий інструмент, а не продукт, яким проєкт відомий. Головний лейбл існує для відображення й для групування порівнюваних репозиторіїв — він ніколи не є підставою для оцінкового рішення.
На що це впливає сьогодні
На одну перевірку, за постійним правилом. Від метрик 2.5.0 очікування щодо файлу блокування залежностей у резервній гілці стану безпеки читає класифікацію: опублікований пакет, чий маніфест декларує виконуваний файл, вважається застосунком і зберігає очікування — тоді як раніше сама лише публікація його знімала.
Постійне правило: скоринг читає лише декларації маніфестів. Лейбл, виведений зі структури файлів, тем чи опису, відображається і фіксується, але ніколи не рухає оцінку — це може лише те, що збірковий маніфест стверджує прямо (запис bin, точка входу консольного скрипта, OutputType). Усе інше в класифікації залишається даними: metrics.classification у кожному звіті, разом зі свідченнями, які її породили. Подальші під'єднання фіксуватимуться у версіях методології в міру появи.
Дивіться також: підтримувані екосистеми · індекс здоров'я · стан безпеки · конфігурація сканування · сигнали, а не гарантії