Репозиторій — це не просто «проєкт». Він щось будує, і саме те, що він будує, визначає, яких практик від нього розумно очікувати. Від опублікованої бібліотеки очікується, що вона не коммітитиме файл блокування залежностей: зафіксовані нею версії однаково проігнорує кожен, хто її встановлює. Від застосунку поруч із нею в каталозі очікується протилежне, бо зафіксовані ним версії — це рівно те, що потрапляє в розгортання. Судити обох за одним правилом означає хибно прочитати одного з них.
До метрик 2.3.0 це питання заміняв єдиний проксі-сигнал: чи публікує репозиторій пакет у реєстрі. За ним кожен інструмент командного рядка на PyPI читається як бібліотека, а кожен застосунок, що принагідно випускає один допоміжний пакет, — так само.
Усі прочитання, які підтверджує доказова база
Класифікація є мультилейбловою. Програмне забезпечення, що є водночас опублікованою бібліотекою і запускним інструментом, — звичайний випадок, а не суперечність, яку треба розв'язати: ripgrep є і крейтом, і бінарником, esbuild є і npm-пакетом, і виконуваним файлом. Тому репозиторій зберігає всі прочитання, які підтверджує його доказова база.
Три питання отримують незалежні відповіді, і репозиторій може відповісти «так» більш ніж на одне:
| Питання | Істинне для | Що робить обґрунтованим очікувати |
|---|---|---|
| Споживається як код | бібліотека, фреймворк, SDK, клієнт API, проміжне ПЗ, драйвер | Стабільний інтерфейс, журнал змін, версіонування, на яке може спиратися інше ПЗ |
| Запускається як програма | інструмент командного рядка, термінальний інтерфейс, десктопний і мобільний застосунок, вебінтерфейс, мережевий сервіс, чат-бот, MCP-сервер | Зафіксовані залежності, гігієна розгортання й конфігурації |
| Встановлюється в хост | плагін, розширення, тема оформлення, інструменти редактора | Хост задає модель довіри й ритм випусків |
Там, де застосовні обидва, застосовні обидва: гібрид несе зобов'язання кожного свого прочитання, а не найм'якшого з них.
Лейбли
| Споживається як код | Запускається як програма | Встановлюється в хост |
|---|---|---|
| Бібліотека | Інструмент командного рядка | Плагін |
| Фреймворк | Термінальний інтерфейс | Розширення |
| SDK | Десктопний застосунок | Тема оформлення |
| Клієнт API | Мобільний застосунок | Інструменти редактора |
| Проміжне ПЗ | Вебінтерфейс | |
| Драйвер | Мережевий сервіс | |
| Чат-бот | ||
| MCP-сервер |
Обчислювальний нотатник — окремий лейбл, що не належить до жодної з трьох груп: його читає й запускає людина, його ніщо не імпортує і нікуди не встановлює.
Як отримано відповідь
Свідчення впорядковані за мірою довіри, і жоден окремий слабкий сигнал не дає лейбла.
| Свідчення | Приклади | Вага |
|---|---|---|
| Оголошено у збірковому маніфесті | запис 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.3.0. Кожен збережений звіт було перекласифіковано з фактів, які він уже містив, але свідчення з маніфестів збираються під час сканування, тож зібрані раніше звіти несуть лише слабші рівні й отримають повне прочитання при наступній інспекції репозиторію.
- Доказова база не відповідає на питання. Багато репозиторіїв не публікують маніфестів, не мають інформативних тем і описують себе прозою, яка не стверджує нічого структурного.
- Відповідь була б здогадом. Там, де сигнали є, але надто слабкі, щоб перетнути поріг, не стверджується нічого.
У всіх трьох випадках звіт просто не показує класифікації. Відсутність ніколи не подається як висновок, на ній нічого не оцінюється, і репозиторій без неї не позначається, не понижується в рейтингу й не штрафується жодним чином.
Репозиторії, що будують кілька речей
Монорепо, у якому поруч живуть придатний до розгортання сервіс і три опубліковані бібліотеки, не є одним артефактом, і згортання його до єдиної відповіді втратило б той факт, що істинні обидва прочитання. Тому кожен маніфест класифікується за власними деклараціями, а репозиторій несе об'єднання.
Один наслідок варто назвати прямо: єдиний головний лейбл, показаний для такого репозиторію, — це найкраще підтверджений, а у великому монорепо ним може виявитися опублікований збірковий інструмент, а не продукт, яким проєкт відомий. Головний лейбл існує для відображення й для групування порівнюваних репозиторіїв — він ніколи не є підставою для оцінкового рішення.
На що це впливає сьогодні
Ні на що. Станом на метрики 2.3.0 класифікація публікується як дані — metrics.classification у кожному звіті, разом зі свідченнями, які її породили, — і жодна метрика її не читає. Під'єднання до метрик, які від неї залежать, починаючи з очікування щодо файлу блокування залежностей, є окремою зміною й буде зафіксоване у версіях методології, коли відбудеться.