Публічний реєстр
Звіт про здоров'я програмного забезпеченнясхема 0.27.0 · метрики 1.13.0 · 2026-07-24 04:48 UTC

alxndrkalinin / cubic

CUDA-accelerated 3D BioImage Computing (ICCV BIC 2025)

PythonMIT★ 31 зірка⑂ 1 форкз вер. 2021 р.Переглянути на GitHub ↗

alxndrkalinin/cubic має індекс здоров’я 64 зі 100, що відповідає смузі «Помірний». Найвищий показник — Vitality (84/100), найнижчий — Community & Adoption (36/100). Останнє оновлення — сьогодні. Більшість нещодавньої роботи виконує один учасник.

64
загалом / 100
Помірний

Індекс здоров'я програмного забезпечення

Метрики згруповано у зважені категорії на шкалі 1–100. Загальна оцінка починається як їхнє середнє; коли публічні дані активують Політику юрисдикцій високого ризику, рейтинг коригується й отримує верхню межу 49 («Під ризиком»). Готовність до ШІ не входить до індексу.

64
Відмінний85-100Зразковий; відповідає практично всім перевіреним критеріям
Добрий70-84Здоровий; незначні прогалини
Помірний50-69Прийнятний, але з помітними прогалинами; рекомендовано перевірку
У зоні ризику30-49Суттєві слабкі місця; впровадження потребує обережності
Критичний1-29Серйозні проблеми (покинутий, єдиний мейнтейнер, без базової гігієни)
ЖиттєздатністьСпільнота тавпровадженняСталість таврядуванняІнженернаякістьБезпекаГотовність доШІ

Профіль оцінок

Кожна вісь — окрема категорія. Форма важить більше, ніж середнє: здоровий об'єкт заповнює всю фігуру, тоді як профіль із піками та провалами означає, що сила в одному вимірі маскує ризик в іншому.

Власність

Alexandr KalininОсобистий обліковий запис
177 підписників107 публічних репозиторіївз жовт. 2011 р.Biohub

Цей репозиторій належить особистому обліковому запису. Проєкт з єдиним власником несе більший ризик безперервності, ніж підтримуваний організацією.

Пакетні екосистеми

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікація
PyPIcubic0.8.0-180 днів тому

Метрики за категоріями

Життєздатність

Чи живий проєкт — чи пишеться код і чи виходять релізи?

84Добрий · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 0 дн. тому
9.7/36Ритм комітів — 14/52 тижнів із комітами
17.8/18Обсяг комітів — 95 комітів за останній рік
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Використані вхідні дані
commits_last_year95
human_commit_share0,93
days_since_last_push0
active_weeks_last_year14
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 17 релізів
36/36Свіжість релізів — останній реліз 0 дн. тому
27/27Ритм релізів — реліз кожні ~6,5 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count17
latest_release_tagv0.8.0
releases_from_tagsні
days_since_latest_release0
mean_days_between_releases6,5
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

Спільнота та впровадження

Чи має проєкт користувачів, завантаження, увагу та влаштовані умови для контриб’юторів?

36У зоні ризику · 18% загального індексу
Як обчислюється оцінка
24/60Зірки — 31 зірок
0/25Форки — 1 форків
0/15Спостерігачі — 2 спостерігачів
Використані вхідні дані
forks1
stars31
watchers2
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
0/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
has_contributingні
has_issue_templateні
has_code_of_conductні
has_pull_request_templateні

Сталість та врядування

Чи переживе проєкт своїх людей — бас-фактор, реактивність, хто за ним стоїть і як супроводжуються пакети?

63Помірний · 24% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
0.1/22.5Розподіл комітів — головний контриб’ютор — автор 100% комітів
2.7/13.5Широта контриб’юторів — 2 контриб’юторів
10/10OpenSSF Scorecard: Contributors — project has 4 contributing companies or organizations
Використані вхідні дані
bus_factor1
contributors_sampled2
top_contributor_share0,997
Як обчислюється оцінка
46.8/46.8Вирішення issue — закрито 100% issue
36.6/38.3Прийняття PR — злито 44/46 вирішених PR
0/15OpenSSF Scorecard: Code-Review — Found 0/12 approved changesets -- score normalized to 0
Використані вхідні дані
merged_prs44
open_issues0
closed_issues5
issue_closed_ratio1
closed_unmerged_prs2
Як обчислюється оцінка
10/30Підтримка власника — особистий (користувацький) обліковий запис
0/20Верифікований домен — не застосовно до користувацьких облікових записів
16.2/25Охоплення власника — 177 підписників у alxndrkalinin
25/25Послужний список — 107 публічних репозиторіїв, вік облікового запису ~14 р.
Використані вхідні дані
followers177
owner_typeUser
is_verified
owner_loginalxndrkalinin
public_repos107
account_age_days5 404
Виключено з оцінювання (немає даних або не застосовно): Верифікований домен. Залишкові ваги перенормовано.

Супровід пакетів

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 1 пакет(ів) у pypi
35/35Свіжість публікацій — остання публікація 0 дн. тому
20/20Історія версій — 18 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packagescubic
ecosystemspypi
any_deprecatedні
min_days_since_publish0

Інженерна якість

Чи наявні базові інженерні практики та документація?

82Добрий · 20% загального індексу
Як обчислюється оцінка
24/24Процеси CI — 3 процес(ів) CI
24/24Наявні тести
16/16Конфігурація лінтера
9.6/9.6Pre-commit-хуки
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 4 out of 4 merged PRs checked by a CI test -- score normalized to 10
Використані вхідні дані
has_ciтак
has_testsтак
has_editorconfigні
has_linter_configтак
has_precommit_configтак

Документація

65Помірний
Як обчислюється оцінка
30/30README
0/25Каталог документації
15/15Сайт документації / домашня сторінка — https://doi.org/10.1109/ICCVW69036.2025.00608
10/10Опис репозиторію
0/10Теми
10/10Wiki
Використані вхідні дані
topics
has_wikiтак
homepagehttps://doi.org/10.1109/ICCVW69036.2025.00608
has_readmeтак
has_docs_dirні
has_descriptionтак

Безпека

Чи міцні видимі практики безпеки й ланцюга постачання, без непослабленої пов’язаності з юрисдикціями високого ризику?

50Помірний · 16% загального індексу

Стан безпеки

38У зоні ризику
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 4 out of 4 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/12 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 4 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
7.5/7.5Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — немає даних
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 48 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate3,8
Виключено з оцінювання (немає даних або не застосовно): signed_releases. Залишкові ваги перенормовано.
Як обчислюється оцінка
35/35Прямі залежності без відомих сповіщень — жодна пряма залежність не має відомих сповіщень
0/25Непрямі залежності без відомих сповіщень — транзитивний набір не відокремлюється від залежностей розробки й тестування в цьому обсязі
0/40Немає задавнених сповіщень — жодне сповіщення не має дати публікації
Використані вхідні дані
sourceosv
advisories84
affected_packages13
assessed_packages166
unassessed_packages1
affected_by_severitycritical 1, high 4, moderate 7, low 1
direct_affected_packages0
Виключено з оцінювання (немає даних або не застосовно): Непрямі залежності без відомих сповіщень, Немає задавнених сповіщень. Залишкові ваги перенормовано. Звірено 166 резолвлених залежностей із OSV. 1 не вдалося оцінити — немає резолвленої версії, непідтримувана екосистема або поза межами звітованого переліку пакетів. Цей репозиторій не публікує пакета, який резолвить індекс, тож натомість оцінено граф залежностей репозиторію. Цей граф змішує закріплені версії для розробки й тестування зі справді постачаними залежностями, тож оцінюються лише задекларовані runtime-залежності; транзитивні знахідки подаються як контекст і в оцінку не входять. Досяжність не аналізується.

Готовність до ШІ

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Незалежний, експериментальний бейдж — вага 0.0, тож він подається окремо і не впливає на загальний індекс здоров'я.

61Помірний · 0% загального індексу
Як обчислюється оцінка
45/45Інструкції для агентів — AGENTS.md, CLAUDE.md
0/15Машиночитана документація (llms.txt)
40/40Читабельна історія комітів — намір зазначено у 93 з 93 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share1
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes9 016
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
11/11Конфігурація лінтера / форматера
0/11Статична перевірка типів
10/10Відтворюване середовище — lockfile
10/10Підтверджена практика роботи з агентами — 76 з останніх 100 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Використані вхідні дані
has_nixні
has_testsтак
lockfilesuv.lock
has_dockerfileні
typed_languageні
bootstrap_files
has_devcontainerні
has_linter_configтак
typecheck_configs
agent_commit_share0,76
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
0/45Типізований код — Python без конфігурації перевірки типів
54.4/55Керовані розміри файлів — 1/93 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languagePython
largest_source_bytes63 861
source_files_sampled93
oversized_source_files1
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
0/20Сервер MCP
40/40Придатні до запуску приклади — examples, notebooks
Використані вхідні дані
example_dirsexamples, notebooks
has_mcp_signalні
api_schema_files

Ключові факти

31зірок GitHub
2контриб'юторів
95комітів за останні 12 місяців
0днів від останнього пушу
17релізів
1бас-фактор
0відкритих issue
PyPIпакетних екосистем

Попередження щодо збору даних

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • deps.dev does not index pypi:cubic@0.8.0; advisories assessed against the repository dependency graph instead

Докладніше

OpenSSF Scorecard 3.8 / 10
3.8сукупно

Незалежна, не прив'язана до інструментів оцінка безпеки від відкритого проєкту OpenSSF Scorecard. Кожна перевірка винагороджує практику безпеки, а не інструмент конкретного постачальника. Перевірки, які Scorecard не зміг визначити, позначено н/д і виключено з оцінки безпеки (вони ніколи не зараховуються як нуль).Scorecard v5.5.0 · 2026-07-24 04:48 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests4 out of 4 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/12 approved changesets -- score normalized to 0
10Contributorsproject has 4 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
н/дSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities48 existing vulnerabilities detected
Прямі залежності 2
РеєстрПакетОбмеження версіїМаніфест
PyPInumpy>=1.20.0pyproject.toml
PyPIscikit-image>=0.16.1pyproject.toml
Усі залежності 167

Повний розв'язаний набір залежностей із графа залежностей GitHub: 2 прямих і 165 непрямих (транзитивних) пакетів. Транзитивне замикання є повним, коли в репозиторії закомічено lockfile.

РеєстрПакетВерсіяЗв'язок
PyPInumpy2.0.2пряма
PyPIscikit-image0.25.2пряма
PyPIanyio4.13.0непряма
PyPIappnope0.1.4непряма
PyPIargon2-cffi25.1.0непряма
PyPIargon2-cffi-bindings25.1.0непряма
PyPIarrow1.4.0непряма
PyPIasttokens3.0.1непряма
PyPIasync-lru2.3.0непряма
PyPIattrs26.1.0непряма
PyPIbabel2.18.0непряма
PyPIbeautifulsoup44.14.3непряма
PyPIbleach6.3.0непряма
PyPIcellpose4.2.1.1непряма
PyPIcertifi2026.1.4непряма
PyPIcffi2.0.0непряма
PyPIcfgv3.5.0непряма
PyPIcharset-normalizer3.4.4непряма
PyPIcolorama0.4.6непряма
PyPIcomm0.2.3непряма
PyPIcontourpy1.3.2непряма
PyPIcubicнепряма
PyPIcuda-bindings12.9.4непряма
PyPIcuda-pathfinder1.3.4непряма
PyPIcycler0.12.1непряма
PyPIdebugpy1.8.20непряма
PyPIdecorator5.3.1непряма
PyPIdefusedxml0.7.1непряма
PyPIdistlib0.4.0непряма
PyPIexceptiongroup1.3.1непряма
PyPIexecuting2.2.1непряма
PyPIfastjsonschema2.21.2непряма
PyPIfastremap1.17.7непряма
PyPIfilelock3.21.0непряма
PyPIfill-voids2.1.1непряма
PyPIfonttools4.62.0непряма
PyPIfqdn1.5.1непряма
PyPIfsspec2026.2.0непряма
PyPIh110.16.0непряма
PyPIhttpcore1.0.9непряма
PyPIhttpx0.28.1непряма
PyPIidentify2.6.16непряма
PyPIidna3.11непряма
PyPIimagecodecs2025.3.30непряма
PyPIimageio2.37.2непряма
PyPIiniconfig2.3.0непряма
PyPIipykernel7.2.0непряма
PyPIipython8.39.0непряма
PyPIipython-pygments-lexers1.1.1непряма
PyPIipywidgets8.1.8непряма
PyPIisoduration20.11.0непряма
PyPIjedi0.20.0непряма
PyPIjinja23.1.6непряма
PyPIjson50.14.0непряма
PyPIjsonpointer3.1.1непряма
PyPIjsonschema4.26.0непряма
PyPIjsonschema-specifications2025.9.1непряма
PyPIjupyter1.1.1непряма
PyPIjupyter-client8.8.0непряма
PyPIjupyter-console6.6.3непряма
PyPIjupyter-core5.9.1непряма
PyPIjupyter-events0.12.1непряма
PyPIjupyter-lsp2.3.1непряма
PyPIjupyter-server2.18.2непряма
PyPIjupyter-server-terminals0.5.4непряма
PyPIjupyterlab4.5.7непряма
PyPIjupyterlab-pygments0.3.0непряма
PyPIjupyterlab-server2.28.0непряма
PyPIjupyterlab-widgets3.0.16непряма
PyPIkiwisolver1.5.0непряма
PyPIlark1.3.1непряма
PyPIlazy-loader0.4непряма
PyPIlibrt0.8.0непряма
PyPImarkupsafe3.0.3непряма
PyPImatplotlib3.10.8непряма
PyPImatplotlib-inline0.2.2непряма
PyPImistune3.2.1непряма
PyPImpmath1.3.0непряма
PyPImypy1.19.1непряма
PyPImypy-extensions1.1.0непряма
PyPInatsort8.4.0непряма
PyPInbclient0.10.4непряма
PyPInbconvert7.17.1непряма
PyPInbformat5.10.4непряма
PyPInest-asyncio1.6.0непряма
PyPInetworkx3.4.2непряма
PyPInodeenv1.10.0непряма
PyPInotebook7.5.6непряма
PyPInotebook-shim0.2.4непряма
PyPInvidia-cublas-cu1212.8.4.1непряма
PyPInvidia-cuda-cupti-cu1212.8.90непряма
PyPInvidia-cuda-nvrtc-cu1212.8.93непряма
PyPInvidia-cuda-runtime-cu1212.8.90непряма
PyPInvidia-cudnn-cu129.10.2.21непряма
PyPInvidia-cufft-cu1211.3.3.83непряма
PyPInvidia-cufile-cu121.13.1.3непряма
PyPInvidia-curand-cu1210.3.9.90непряма
PyPInvidia-cusolver-cu1211.7.3.90непряма
PyPInvidia-cusparse-cu1212.5.8.93непряма
PyPInvidia-cusparselt-cu120.7.1непряма
PyPInvidia-nccl-cu122.27.5непряма
PyPInvidia-nvjitlink-cu1212.8.93непряма
PyPInvidia-nvshmem-cu123.4.5непряма
PyPInvidia-nvtx-cu1212.8.90непряма
PyPIopencv-python-headless4.13.0.92непряма
PyPIoverrides7.7.0непряма
PyPIpackaging26.0непряма
PyPIpandocfilters1.5.1непряма
PyPIparso0.8.7непряма
PyPIpathspec1.0.4непряма
PyPIpexpect4.9.0непряма
PyPIpillow12.1.1непряма
PyPIplatformdirs4.6.0непряма
PyPIpluggy1.6.0непряма
PyPIpooch1.9.0непряма
PyPIpre-commit4.5.1непряма
PyPIprometheus-client0.25.0непряма
PyPIprompt-toolkit3.0.52непряма
PyPIpsutil7.2.2непряма
PyPIptyprocess0.7.0непряма
PyPIpure-eval0.2.3непряма
PyPIpycparser3.0непряма
PyPIpygments2.19.2непряма
PyPIpyparsing3.3.2непряма
PyPIpytest9.0.2непряма
PyPIpython-dateutil2.9.0.post0непряма
PyPIpython-json-logger4.1.0непряма
PyPIpywinpty3.0.3непряма
PyPIpyyaml6.0.3непряма
PyPIpyzmq27.1.0непряма
PyPIreferencing0.37.0непряма
PyPIrequests2.32.5непряма
PyPIrfc3339-validator0.1.4непряма
PyPIrfc3986-validator0.1.1непряма
PyPIrfc3987-syntax1.1.0непряма
PyPIroifile2025.12.12непряма
PyPIrpds-py0.30.0непряма
PyPIruff0.15.0непряма
PyPIscipy1.15.3непряма
PyPIsegment-anything1.0непряма
PyPIsend2trash2.1.0непряма
PyPIsetuptools82.0.0непряма
PyPIsix1.17.0непряма
PyPIsoupsieve2.8.4непряма
PyPIstack-data0.6.3непряма
PyPIsympy1.14.0непряма
PyPIterminado0.18.1непряма
PyPItifffile2025.5.10непряма
PyPItinycss21.4.0непряма
PyPItomli2.4.0непряма
PyPItorch2.10.0непряма
PyPItorchvision0.25.0непряма
PyPItornado6.5.6непряма
PyPItqdm4.67.3непряма
PyPItraitlets5.15.0непряма
PyPItrimesh4.11.2непряма
PyPItriton3.6.0непряма
PyPItyping-extensions4.15.0непряма
PyPItzdata2026.2непряма
PyPIuri-template1.3.0непряма
PyPIurllib32.6.3непряма
PyPIvirtualenv20.36.1непряма
PyPIwcwidth0.7.0непряма
PyPIwebcolors25.10.0непряма
PyPIwebencodings0.5.1непряма
PyPIwebsocket-client1.9.0непряма
PyPIwidgetsnbextension4.0.15непряма
Сповіщення про залежності 13

Цей репозиторій не публікує пакета, який розпізнає індекс, тож оцінено його власний граф залежностей — 166 пакетів, серед яких є й піниї розробки та тестування, що ніколи не постачаються: 13 мають відомі сповіщення, з них 0 прямі. 1 не вдалося оцінити — немає резолвленої версії, непідтримувана екосистема або поза наведеним переліком пакетів.

ПакетВерсіяЗв'язокКритичністьСповіщеньВиправлено в
pillow12.1.1непрямакритична3612.3.0
jupyterlab4.5.7непрямависока64.6.2
mistune3.2.1непрямависока203.3.0
torch2.10.0непрямависока22.13.0
urllib32.6.3непрямависока42.7.0
bleach6.3.0непрямапомірна36.4.0
idna3.11непрямапомірна23.15
jupyter-server2.18.2непрямапомірна22.20.0
pytest9.0.2непрямапомірна29.0.3
requests2.32.5непрямапомірна22.33.0
setuptools82.0.0непрямапомірна283.0.0
tornado6.5.6непрямапомірна16.5.7
pygments2.19.2непряманизька22.20.0

Сповіщення означає, що версія, записана в графі залежностей, потрапляє в уражений діапазон. Досяжність не аналізується, а граф містить піниї розробки й тестування — знахідка може стосуватися інструментів, а не поставленого коду.

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 3738,
      "has_wiki": true,
      "homepage": "https://doi.org/10.1109/ICCVW69036.2025.00608",
      "languages": {
        "Python": 727831
      },
      "pushed_at": "2026-07-24T01:07:49Z",
      "created_at": "2021-09-28T09:11:24Z",
      "owner_type": "User",
      "updated_at": "2026-07-24T01:07:52Z",
      "description": "CUDA-accelerated 3D BioImage Computing (ICCV BIC 2025)",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "https://alxndrkalinin.github.io",
      "name": "Alexandr Kalinin",
      "type": "User",
      "login": "alxndrkalinin",
      "company": "Biohub",
      "location": "San Francisco, CA",
      "followers": 177,
      "avatar_url": "https://avatars.githubusercontent.com/u/1107762?v=4",
      "created_at": "2011-10-06T14:51:18Z",
      "is_verified": null,
      "public_repos": 107,
      "account_age_days": 5404
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-07-24T01:07:59Z"
        },
        {
          "tag": "v0.8.0a2",
          "kind": "other",
          "published_at": "2026-06-19T05:37:01Z"
        },
        {
          "tag": "v0.8.0a1",
          "kind": "other",
          "published_at": "2026-06-15T21:44:04Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-06-12T16:45:51Z"
        },
        {
          "tag": "v0.7.0a13",
          "kind": "other",
          "published_at": "2026-06-11T05:29:26Z"
        },
        {
          "tag": "v0.7.0a12",
          "kind": "other",
          "published_at": "2026-06-05T20:39:53Z"
        },
        {
          "tag": "v0.7.0a11",
          "kind": "other",
          "published_at": "2026-06-04T00:50:37Z"
        },
        {
          "tag": "v0.7.0a10",
          "kind": "other",
          "published_at": "2026-06-02T22:57:12Z"
        },
        {
          "tag": "v0.7.0a9",
          "kind": "other",
          "published_at": "2026-06-01T23:38:53Z"
        },
        {
          "tag": "v0.7.0a7",
          "kind": "other",
          "published_at": "2026-05-26T20:55:44Z"
        },
        {
          "tag": "v0.7.0a6",
          "kind": "other",
          "published_at": "2026-05-23T00:45:27Z"
        },
        {
          "tag": "v0.7.0a5",
          "kind": "other",
          "published_at": "2026-05-22T05:10:51Z"
        },
        {
          "tag": "v0.7.0a4",
          "kind": "other",
          "published_at": "2026-05-22T01:37:07Z"
        },
        {
          "tag": "v0.7.0a2",
          "kind": "other",
          "published_at": "2026-04-02T22:30:08Z"
        },
        {
          "tag": "v0.7.0a1",
          "kind": "other",
          "published_at": "2026-03-10T20:55:10Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-02-12T19:26:02Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2025-10-23T22:33:06Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "e354584402a0cbc16d2b2130c8e8bdd14baeb39b",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013mavJKPWTmp46kH6cLBsB7",
          "is_bot": false,
          "headline": "chore: release version 0.8.0",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-07-24T01:07:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0e6f4b66feff2b375322c209e4fdbe718133cc9f",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-01T21:08:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee72839050566ec776aea5fce12bb06033295fc2",
          "body": "…tebook\n\nRework the feature extraction example to demonstrate device-agnostic\nregionprops: the same regionprops_table call runs on CPU (scikit-image)\nand GPU (cuCIM), timed on both with a parity check confirming the feature\nmatrices are identical up to floating-point precision (~8x faster on an\nA40)\n[…]\ned outputs, mirroring the segmentation tutorial. Also adds the\npaired nbconvert script and updates the README example description.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(examples): add CPU vs GPU comparison to 3D feature extraction no…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-07-01T21:08:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "687358a34281c2b03b6773836527c25439e2d70e",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-19T05:36:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb04eef0e7d3531baf28166a5c35a84782da4ddf",
          "body": "…fast RL deconvolution (#52)\n\nAdds an unmatched Wiener-Butterworth (WB) back projector to Richardson-Lucy deconvolution (Guo et al. 2020), converging in ~1-2 iterations instead of 10-50. The matched path is byte-for-byte unchanged by default.\n\n- create_backprojector (device-agnostic NumPy/CuPy port \n[…]\n_finder; faithful unmatched RL update, circulant only.\n- Example notebook + paired script + README row.\n- Version bump to 0.8.0a2.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(preprocessing): Wiener-Butterworth unmatched back projector for …",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-19T05:36:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6dbf90e4e31bc945940242f0fe0f440f1f8ac7d6",
          "body": "…ion (#51)\n\n* feat(segmentation): support all Cellpose v4 models in GPU-resident path\n\nRename the GPU-resident entry point to segment_cellpose and cover every\nCellpose v4 model -- the SAM backbone (cpsam, cpsam_v2) and the DINOv3\nbackbones (cpdino, cpdino-vitb). The backbones differ only in the defa\n[…]\n.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Support all Cellpose v4 models (SAM + DINO) in GPU-resident segmentat…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-15T21:41:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dad42090d825e714ea0607d8eae0eca128d802c8",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: release version 0.7.0",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-12T16:45:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "22be6035ef053f6cd89a9af26a99a929db2505b5",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a13",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-11T05:29:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1cd5f089a676b2460e20ad4a39eeefc515694110",
          "body": "morphology.square/cube receive only an int, so the device-agnostic proxy\nreturns a host footprint; cuCIM's erosion rejects a NumPy footprint paired\nwith a GPU mask (footprint must be an ndarray or Sequence). Move the\nfootprint onto the mask's device before erosion, matching the existing\nto_same_device pattern in segment_utils.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): move SSIM mask footprint to mask device for cuCIM erosion",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-11T05:28:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3904255a7db04aa0d401fac647aa9da700a13c45",
          "body": "The install block omitted the `plot` (matplotlib) and `examples` (jupyter,\npooch) extras, though the plotting helpers and the example notebooks in the\nUsage section require them. Also list the image-quality metrics (PSNR, SSIM,\nMicroSSIM, MS-SSIM) now exported from cubic.metrics in the feature overview.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: document plot/examples extras and image-quality metrics in README",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:41:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "843dba1af584ffae00a61594ca665bcaee257f53",
          "body": "The test imported matplotlib at module top, so CI (`uv sync --extra dev`,\nwhich omits the [plot] extra) hit a collection-time ImportError that\naborted the entire pytest session. Guard with\n`pytest.importorskip(\"matplotlib\")` like the other optional-dependency\ntests (e.g. trimesh in test_mesh.py) so the module skips cleanly instead.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(plot_utils): skip when optional matplotlib extra is absent",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b1e40652e4044e215b29a3d8970ab2be55785a11",
          "body": "…allback\n\nThe skimage keyword-dispatch test passed the array under `image=`, which\nthe old first-arg/`image`-only detection already inspected, so it did not\nactually guard the regression. Switch to `measure.label(label_image=...)`,\na keyword the old code never looked at.\n\nAdd a SciPy test that monkeypatches the cupyx import to fail for a GPU\ninput and asserts the proxy warns, computes on CPU, and moves the result\nback to the GPU.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(proxy): cover keyword dispatch via label and cupyx-unavailable f…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e70e15d10e416f1c14d6b94532f54dcd6ccd89ba",
          "body": "A non-positive sigma forced truncate=0.0 and still called the Gaussian\nfilter, yielding confusing backend-dependent behaviour instead of a clear\nerror. Reject non-finite or non-positive sigma at the ms_ssim entry point,\nmatching the existing kernel_size/data_range validation.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): validate sigma is finite-positive in ms_ssim",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d062fbc61165426447ed6c719e291909c020d9af",
          "body": "…ng_objects\n\nLabels can share neighbours or be revisited, so the list accumulated\nduplicate ids and the `mask_idx in exclude_masks` membership check was\nO(n) per iteration. Use a set[int] with add/update for O(1) membership\nand no duplicate work in the final zeroing pass. Behaviour is unchanged.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(segmentation): dedupe exclude_masks via set in remove_touchi…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "59a20a5ea3ba2a2dc31fd75b8fbb3e2877042fca",
          "body": "crop_from_end evaluated `axis == axes[-2]` unconditionally (the left\noperand of `and` is always evaluated), so a single-axis call raised\nIndexError even for corners without \"b\" (e.g. \"tl\"/\"tr\"/\"br\") that the\nprevious implementation handled. Only consult axes[-2] when a\nsecond-to-last axis exists.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(image_utils): guard crop_corner against single-axis inputs",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "557c6998c30cf08c72db053f75f4741cf78e014b",
          "body": "…stic\n\nshow_image_error's docstring said \"between teo images\"; correct to \"two\".\n\nis_gpu_array's docstring claimed a non-array object carrying a device\nattribute is \"not misclassified\", but the implementation treats any\nnon-\"cpu\" string device as GPU. Reword to describe the actual device-based\nheuristic (CuPy Device/CUDA tensor -> GPU; numpy \"cpu\"/no device -> CPU;\nnon-\"cpu\" string device -> GPU) so the contract is not misleading.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: fix show_image_error typo and clarify is_gpu_array device heuri…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2cf9782d02d87e1079724fb07eacaabdb4b77913",
          "body": "_torchmetrics_ssim_update already builds the spatial crop slice once; reuse\nit for the contrast-sensitivity crop instead of rebuilding the identical\nslice.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(metrics): reuse the computed crop slice in ms_ssim",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ec9d993646972412adf6003603bc719c65cd8734",
          "body": "…e proxies\n\nThe \"scan every arg for a GPU array\" and \"coerce GPU args to host\" steps were\nduplicated verbatim in both proxies. Hoist them into cuda.py as any_gpu_arg\nand coerce_args_to_cpu (next to is_gpu_array) so the routing contract lives in\none place; the scipy-only result re-upload stays in the proxy.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(cuda): share device-routing helpers between scipy and skimag…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ca848acd2968eb7b2afa9af8480f1fb82096cfba",
          "body": "show_image_error set vmin=-(2**bit_depth) - 1 but vmax=2**bit_depth - 1,\nso the diverging colormap was not centered on zero. Make the limits\nsymmetric.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(plot_utils): center error-map color limits on zero",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2b6a4e5323781eedaaadbe81e4b41cc59e9a068b",
          "body": "np.unique kept label 0, so extract_features built a meaningless background\nmesh and emitted a spurious label-0 row inconsistent with voxel.regionprops.\nDrop the background label, matching the voxel convention.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(feature): exclude background label from mesh.extract_features",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e4304a3da7332f00d205f58acedfe66d14f48f53",
          "body": "When spacing was None, _radial_edges_cached ignored use_max_nyquist and\ncapped at min(n // 2). Sectioned FSC/DCR then normalized by max(n // 2),\ncompressing the XY-sector curve into the low-frequency quarter on\nanisotropic shapes (the default dcr_resolution path). Honor the flag for\nindex units; the Z sector is unaffected since its frequencies only reach\nthe min Nyquist.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): honor use_max_nyquist for index-unit radial edges",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b3e56ddcbf82fd0f78a2d9b701cd6b9ee62b19d5",
          "body": "The precomputed-features branch compared base names (e.g. \"centroid\")\nagainst the expanded column names (\"centroid-0\"), raising a spurious\nAssertionError for any vector property. Compare against base names, as the\nsibling branch already does.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): match base feature names in get_true_features",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "577a32bf6b7b69c5fd74653934f97baba48466f6",
          "body": "When the caller supplies matches_per_threshold, the sequential-label check\nin compute_matches is bypassed, so taking object counts via masks.max()\nover-counted on gapped label ids and corrupted FP/FN/AP. Count distinct\nforeground labels instead.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): count distinct labels in average_precision",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ae82674ccb01c3b7e0e9ad965ebf5253ffa0a749",
          "body": "The reflect-pad and crop tracked kernel_size while the Gaussian radius was\nfixed by sigma/truncate, so for any kernel_size below the Gaussian radius\nthe filter leaked cval=0 into the valid region. Derive skimage's truncate\nas pad/sigma so the kernel is exactly kernel_size wide (matching\ntorchmetrics\n[…]\naking the betas product. Reduce per image and average the\nper-image products instead (torchmetrics' elementwise_mean); 2D results\nare unchanged.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): tie ms_ssim kernel to kernel_size and reduce per image",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5a731aa3a31c169b499f082a91eda4a605baee6f",
          "body": "The SciPy and scikit-image proxies detected the target device from only\nthe first positional argument (or input/image). A GPU array passed under\nany other keyword routed to CPU SciPy/scikit-image and crashed on the raw\nCuPy input, and the CPU branch never coerced. Add a shared is_gpu_array\nhelper, scan every positional and keyword argument, and coerce stray GPU\narrays to host on the CPU branch. Also drop the dead io-branch array read.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(cuda): scan all args for device in scipy/skimage proxies",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "15f80b2bab8712e67caade598996ec085c4df899",
          "body": "…error\n\nremove_touching_objects added border_value (=100) to outline pixels and\ntreated any value > border_value as a touch. Because Cellpose routinely\nemits hundreds of labels, every label id above 100 was misread as touching\nand non-touching objects were silently deleted. Read neighbour labels\ndir\n[…]\nhe tuple (ValueError, err_msg), which Python rejects\nwith TypeError, so the shape-mismatch message never surfaced. Raise the\nexception properly.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(segmentation): detect touching objects directly and raise proper …",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d73bbe6c4c47b6437d97480b0173c37e3ee9d190",
          "body": "… path\n\ndecon_skimage/decon_xpy sliced restored_image[pad:..., :, :], assuming 3D\nand raising IndexError on 2D input. Slice the first axis only so the same\ncode works for (H, W) and (Z, Y, X).\n\nrichardson_lucy_skimage's observer path looped num_iter=1 on the previous\noutput, which re-clips every ite\n[…]\nucy\nfrom the original image at each depth so every snapshot is the true\ni-iteration result and the final value matches a single num_iter=n call.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(preprocessing): rank-agnostic decon slicing and faithful observer…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c0ce5218b82c0f4caa7f2ba44ff8fe1d8464a0bb",
          "body": "…ding\n\ncrop_corner(\"br\") had neither a \"t\" nor \"l\" letter, so both axes fell\nthrough to a full slice and the function returned the entire image\n(reachable via crop_br in the FRC local-resolution sweep). Rewrite the\nper-axis edge selection so each of tl/tr/bl/br takes the right block.\n\npad_image_to_s\n[…]\n element short and tripped its assert. Pad with\ncrop_center's centering convention instead so it reaches the exact target\nshape and round-trips.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(image_utils): correct bottom-right crop and centered odd-size pad…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-10T23:05:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0523a4962a41d6a55845a6f93d5a0c0772327f1e",
          "body": "The object API regionprops gained the same extra_properties passthrough\nas regionprops_table but was untested. Add a companion test that checks\nthe custom property is exposed as a per-region attribute with the\ncorrect value, keeping both APIs covered and in sync.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(feature): cover extra_properties forwarding via regionprops",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9f6746637123587f959bc441c620fda95320fd91",
          "body": "Reject an empty `distances` (which left `offsets` empty and divided the\nper-direction average by zero) and any non-positive distance (distance 0\nyields the all-zero self-offset; negative distances yield negated offsets\nthat are meaningless for a GLCM). Fail fast with a ValueError, matching\nthe existing levels/ndim/mask validations.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(feature): validate distances in glcm_features",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5742141c042ea9bc16a5ed7e7a833dfe42a4fac2",
          "body": "Two cleanups from a quality pass, both behavior-preserving (graycoprops\nparity unchanged at <=1e-9):\n\n- Compute the direction-independent level-index ramps (i, j, diff**2,\n  |diff|) once in glcm_features and pass them to _haralick_props instead\n  of rebuilding them on every one of the up-to-13 per-d\n[…]\nder directly from the returned dict, and average a list of\n  per-direction dicts rather than hand-accumulating into a totals dict.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(feature): hoist GLCM index ramps and drop the _PROPS duplicate",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4f6f6b8de0a4546609266036a6a6e1c6f6293431",
          "body": "The empty-pair guard assigns a float64 zero matrix, which makes mypy\ninfer `counts` as float64; the populated branch then reassigned the int\nresult of `np.bincount(...).reshape(...)` before the cast, which the\nstricter CI mypy stubs reject as an incompatible assignment. Produce the\nfloat64 matrix in a single expression so both branches share the type.\nRuntime behavior is unchanged (the matrix was always cast to float64).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(feature): build GLCM counts as float64 in both guard branches",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5d7c30ed6b81683991a5516c4c5858196c40dcd0",
          "body": "When a direction has no valid pairs — an empty overlap region (e.g. a\nsingle-row image's vertical offsets) or a fully masked-out direction —\nthe co-occurrence index array is empty. `cupy.bincount` raises on empty\ninput (it reduces `x.max()` to size the output, which has no identity),\nwhereas `numpy.\n[…]\nields the same properties skimage gives for an empty co-occurrence\nmatrix (contrast/entropy 0, correlation 1.0 via the std guard).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(feature): handle empty-pair GLCM directions on CuPy",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f1fca838b287da6197ac72067c09ff270bcb1336",
          "body": "Surfaces the new cubic.feature.glcm_features API and the\nregionprops_table extra_properties passthrough so downstream consumers\n(dynacell CP feature track) can pin against it.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a12",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fabf093a7f6260f49dfe47086ea1ea6628d89eaa",
          "body": "Add `cubic.feature.glcm_features`, a Haralick gray-level co-occurrence\nmatrix extractor for 2D (H, W) and 3D (D, H, W) images that runs on\nNumPy or CuPy arrays through duck typing. cuCIM has no graycomatrix\n(rapidsai/cucim#530) and skimage's is 2D-only, so the co-occurrence\nmatrix is accumulated wit\n[…]\nalue_range quantizes several regions over a\nshared set of levels. An optional boolean mask restricts counting to\nforeground pairs.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(feature): add device-agnostic GLCM texture features",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5d6f5f4ad04b0e512de78520a3615b8cfcee9ebb",
          "body": "…s_table\n\nAdd an `extra_properties` parameter to `regionprops` and\n`regionprops_table` that forwards user-defined `func(regionmask,\nintensity)` callables to the underlying skimage/cucim implementation\n(both accept it). This lets callers compute custom per-region statistics\n(e.g. intensity percentiles, gradient/Laplacian summaries) in the same\ndevice-agnostic pass as the built-in properties.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(feature): forward extra_properties in regionprops and regionprop…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "dd5075daebfd85bff0a8ac7bdc006600ffabd8ba",
          "body": "Replace `list(set(properties + [\"label\"]))` with an order-preserving\n`list(dict.fromkeys(...))`. A bare `set()` iterates in an order that\ndepends on the interpreter hash seed, which differs per spawned process\nworker. Under a process-based executor each worker would therefore emit\nregionprops_table \n[…]\nr feature matrix. The default serial executor masked this,\nbut the dedup must be deterministic for a stable named-column contract.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(feature): preserve property order in regionprops_table",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-05T20:39:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7f6b96d169a09eb65f20911984cd47ae3bafe54c",
          "body": "Covers the average_precision return_iou passthrough on top of\nv0.7.0a10.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a11",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-04T00:50:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "574e6bb0f6e04055ff85ae57d10594166396ae6c",
          "body": "average_precision already computes the object-overlap IoU internally\n(via compute_matches) and discards it. Add a return_iou flag that\nsurfaces that matrix as a fifth return element so a caller needing a\nDice/overlap metric can reuse the single overlap pass instead of\nrecomputing it. When matches ar\n[…]\n the prior `# type: ignore[assignment]`. Default return_iou=False\npreserves the existing 4-tuple contract for all current callers.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add return_iou passthrough to average_precision",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-03T23:16:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a6735e7752160756370d99c4a3bb8f9f8697b1b4",
          "body": "Covers the deconvolution example data move to Zenodo + pooch\nauto-download (#48) on top of v0.7.0a9.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a10",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-02T22:56:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e9270a09e83b5a77f36ff5946a2de86be98b5fef",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-02T22:45:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26e41630b90d865652c73b538e49ffe1eab4808b",
          "body": "…ownload\n\nRefreshes the notebook outputs from a clean GPU kernel run after the\nswitch to pooch/Zenodo fetching (#48). Cells 0-2 now show the\nend-to-end bootstrap (GPU available, pooch download path, image/PSF\nshapes), and execution counts are renumbered sequentially. All\nreported resolution values a\n[…]\nr 41, DCR XY 919->785 nm / Z 974->874 nm); only per-iteration\nFSC improvement figures differ at ~1e-5 from GPU FP non-determinism.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(examples): re-execute deconvolution notebook with Zenodo auto-d…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-02T22:45:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "61050bf7f6480585b69b3b6d48cefe5373dd9ceb",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-02T20:08:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0494f4e29c3ac34cb4c879b6a3aa649af0774482",
          "body": "…d (#48)\n\n* chore(scripts): add Zenodo upload tooling for example datasets\n\nAdds scripts/zenodo_upload.py and a sidecar metadata JSON used to\npublish the cubic deconvolution example data (3D astrocyte nuclei\nand theoretical PSF) on Zenodo. The script creates an empty\ndeposition via the REST API, att\n[…]\nOpus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(examples): host deconvolution data on Zenodo + pooch auto-downloa…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-02T20:07:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b84db9afbb58cc0a7b53fc739accf0bc178050a2",
          "body": "PyPI already holds cubic-0.7.0a8 from an earlier release and rejects\nfile-name reuse, so skip ahead to a9. Covers PRs #42-#46 on top of\nv0.7.0a7.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a9",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-01T23:38:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "32fcb06bdc545f91ffc91a803e25f37aecfddf9e",
          "body": "Resets the version after v0.7.0a8/a9/a10 tags were deleted before\npublish. Covers PRs #42, #43, #44, #45, and #46 on top of v0.7.0a7.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a8",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-01T22:45:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "256cc9d408fd8a7f57f312cf5671d3d86d462a91",
          "body": "… (#46)\n\n* feat(segmentation): migrate Cellpose wrapper to v4 (SAM) CellposeModel API\n\nCellpose 4 removed the `Cellpose` class and the `model_type`/`omni`/\n`channels` arguments. Rewrite `cellpose_eval`/`cellpose_segment` to use\n`CellposeModel(gpu=True, pretrained_model=\"cpsam\")` with `channel_axis`,\n[…]\nOpus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(segmentation): GPU-resident Cellpose-SAM eval + v4 API migration…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-06-01T20:56:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9aabffc7c149a84e36d4c7238cbe59b35099dcc9",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a10",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T05:13:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "de24edc120ab98a9c13c14152fa51cb62db92f73",
          "body": "…s threshold (#45)\n\n* fix(metrics): return NaN when FSC/FRC curve never legitimately crosses threshold\n\n`first_guess` previously returned `x[0]` when the FSC/FRC curve was\nalready below the threshold at the lowest measured frequency (typical\nof predictions with ~zero correlation to GT). That tiny se\n[…]\nOpus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): return NaN when FSC/FRC curve never legitimately crosse…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T05:12:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0e37ecdbbe92eb2da17280d6e0f7b86f21e98b7f",
          "body": "… min_size= (#44)\n\n* fix(segmentation): handle empty FOVs + migrate off deprecated skimage min_size=\n\nTwo unrelated cleanups around `cleanup_segmentation`:\n\n1. `check_labeled_binary` previously `assert`-ed `len(unique_values) > 1`,\n   so passing an all-zero label mask (a legitimate \"no cells detecte\n[…]\nOpus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(segmentation): handle empty FOVs + migrate off deprecated skimage…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T04:51:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "09f315acb00db74829fe0e9b24b1641885610f3c",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a9",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T00:57:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4bca3a1769e5ec5b54c918c406a130db0abcbcd7",
          "body": "…mpy ≥2.2) (#43)\n\nnp.in1d was deprecated in numpy 1.25 and removed in numpy 2.2. np.isin is\nthe drop-in replacement; for the 1-D indices array used here the two are\nbehaviorally identical (np.in1d always flattens, np.isin preserves shape,\nand indices is already 1-D from np.arange).\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(segmentation): use np.isin in clear_border (np.in1d removed in nu…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T00:57:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d46e345b96671a3559c6e4a094c39ebed3513358",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-29T00:01:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67b916e3665bf4c167ebdf01018169708bbc069f",
          "body": "…n-center FSC values\n\nRe-executed on GPU after the preprocess_images mean-centering fix.\nNotable outcome: 3D FSC Z resolution drops from 4.9898 to 4.3631 µm\n(−12.6%) as the DC×Hamming low-frequency artifact no longer pollutes\nthe low-k FSC bins where Z lives in this anisotropic volume. XY,\nDCR, and 2D-slice metrics shift within expected ranges.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(examples): refresh 3D resolution notebook outputs with post-mea…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T00:00:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "be90037e67ae3e0043d7ad0f3f26a5ca50c083c4",
          "body": "…lution notebook\n\nax.imshow(np.asarray(<cupy_array>)) raises TypeError on recent CuPy\n(>=14) because implicit numpy conversion is disallowed. Replaces three\ndisplay calls in the notebook (and the auto-generated script) with\nasnumpy() and adds it to the import list. Computed FRC/DCR values are\nunchanged — the bug was display-only and only fired when USE_GPU=True.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(examples): use asnumpy() for plt.imshow on cupy arrays in 2D reso…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-29T00:00:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e4a926c9c723d1992b13baf3c27c0bf1069e60ef",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a8",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-28T23:59:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6cec44bd785b05d175ab61deffdbfce30bd5d6a9",
          "body": "…ing (#42)\n\n* fix(metrics): mean-center before Hamming window in FRC/FSC preprocessing\n\npreprocess_images was applying the Hamming taper directly to the raw\nimage. With a large DC offset μ the taper produces a μ·(w(x)−mean(w))\nlow-frequency artifact that survives the later image−image.mean() DC\nremo\n[…]\nOpus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): mean-center before Hamming window in FRC/FSC preprocess…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-28T22:49:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "908a22f512c2640ed299d37edf8f39c54f418a88",
          "body": "* feat(metrics): expose alpha_max kwarg in microssim; bump default to 1e6\n\nAdds alpha_max to get_ri_factor / get_global_ri_factor / MicroSSIM.__init__\nso callers can lift the bracket cap for pathological fits without monkey-\npatching internals. Bumps the default from 1e3 to 1e6 — the old cap could\ns\n[…]\nhropic.com>\n\n* chore: bump version to 0.7.0a7\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): expose alpha_min + alpha_max kwargs in microssim (#41)",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-26T20:49:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "90f9311307b0f8237f9b7179ce3b36b115a9968c",
          "body": "Picks up the torch CUDA → cupy routing fix in @scale_invariant so\ntorch CUDA tensors stay on GPU through cubic.metrics.pcc/ssim/psnr/nrmse\n(zero-copy via __cuda_array_interface__).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a6",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-23T00:45:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "70a43fe576c3bc538292fe8db13120cd585473e1",
          "body": "_canonicalize_torch was using asnumpy() for all torch tensors, forcing\na GPU→CPU transfer even when CuPy is available. For a torch CUDA tensor\nwith CuPy present, cupy.asarray() now creates a zero-copy view via\n__cuda_array_interface__ so computation stays on GPU.\n\nCPU torch tensors and environments without CuPy continue to use the\nasnumpy path unchanged.\n\nTest: asserts torch CUDA → cupy.ndarray with identical GPU pointer.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(metrics): torch CUDA tensors route to cupy, not numpy, in decorator",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T06:21:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c2933e6561d866aeea4a05aa6369e0c87209972d",
          "body": "Bundles cubic-side Phase 1 prerequisites for metric unification:\n- pcc: Pearson correlation with mask + device-agnostic dispatch\n- nrmse/psnr normalize='min_max': per-input normalization\n- ssim spatial_dims=: 5D [N,C,(D,)H,W] batched dispatch\n- torch interop: asnumpy/get_device accept torch tensors\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a5",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T05:10:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "dafe76ad9dfea51373cfebdf73e3d206425d9c6b",
          "body": "…l_dims for 5D inputs\n\nnrmse/psnr: new normalize='min_max' kwarg rescales each input\nindependently to [0, 1] before computing the metric.\n\nssim: new spatial_dims= kwarg dispatches over [N, C, (D,) H, W]\nbatched inputs by iterating over the N*C slabs. Supports\ngaussian_weights=True for a standard 11-\n[…]\nraise,\nbatched dispatch matches loop, spatial_dims rejects wrong ndim,\ntorch tensor parity vs inline torch SSIM kernel (< 1e-3).\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add normalize='min_max' to psnr/nrmse; add ssim spatia…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T05:10:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "569781d795b2f3486c2064c9f82e97ee05d91c23",
          "body": "New cubic.metrics.pcc function with @scale_invariant decorator,\nmask support, and device-agnostic dispatch (NumPy/CuPy). Exported\nfrom cubic.metrics. Also exports nrmse (was importable but not in\n__all__).\n\nTests: identity, anticorrelated, corrcoef parity, constant→nan,\nmask, scale_invariant no-op, shape mismatch, return type, GPU.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add pcc (Pearson correlation coefficient)",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T05:09:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b8dcc275399e4f22ce4e6176ab340c92ce824bb8",
          "body": "- _is_torch_tensor() lazy import helper (no hard dep on torch)\n- get_device() returns \"GPU\"/\"CPU\" for torch CUDA/CPU tensors\n- asnumpy() materializes torch.Tensor via .detach().cpu().numpy()\n- ascupy() docstring documents the read-only contract for CAI views\n- Tests: CPU/CUDA roundtrip, grad detach, device check, no-mutate\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cuda): recognize torch tensors in asnumpy/get_device",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T05:09:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4214221fe804837904f76fdd33175903eb0f46e0",
          "body": "The pre-commit mypy hook ran across the whole tree, which had two\nside effects:\n1. tests/conftest.py + tests/metrics/microssim/conftest.py triggered\n   \"Duplicate module named 'conftest'\" because mypy couldn't tell\n   they live in unrelated test directories.\n2. examples/scripts/*.py — auto-generated\n[…]\n examples/scripts/*.py files — pre-existing\nwhitespace issues unrelated to the MicroSSIM port but flagged on\nevery pre-commit run.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: scope pre-commit mypy hook to cubic/ and fix whitespace hygiene",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T01:35:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c3121e7658a501e1197434a5f2c7e889ca9cc651",
          "body": "Fit and score on a CuPy array end-to-end (compute_norm_parameters ->\nnormalize_min_max -> compute_ssim_elements -> get_global_ri_factor ->\nscore), then compare against the NumPy result; assert agreement to\n1e-4. Both tests gated by pytest.importorskip(\"cupy\"), so they\nauto-skip on CPU-only hosts.\n\nC\n[…]\npreviously only exercised by\ntest_image_processing's percentile path. These tests drive the whole\npublic surface on a CuPy device.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(metrics): add test_xp_dispatch for MicroSSIM and MicroMS3IM",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T01:32:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e32159e0616273c230776aa9cfe02b72e1ec9c40",
          "body": "Previously MicroMS3IM was exercised only by the frozen-fixture upstream\nparity test. Add direct unit tests at 256x256 (above the 176-px floor\nfor 5-level MS-SSIM):\n\n- score() validation: pre-fit, 3-D rejection, shape mismatch,\n  return_individual_components warning\n- Identity: score(x, x) > 1 - 1e-6\n[…]\nam-matching key set, finite values\n- Convenience function micro_multiscale_structural_similarity:\n  preserves stack/list semantics\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(metrics): add standalone MicroMS3IM tests",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T01:31:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fa94e5f2fbacaf23e2816051daa2cd228fb1bba1",
          "body": "…global_ri_factor\n\nMicroSSIM.fit reimplemented an exact verbatim copy of the per-slice\nelement-pooling logic inside get_global_ri_factor (same gaussian_weights=\nFalse, same win_size=7, same per-slice data_range, same C1/C2-from-last-\nslice convention). Replace the 30-line duplicate with a single cal\n[…]\n for laziness here).\n\nBit-identical: 6/6 frozen upstream parity tests pass at 1e-3; full\nmicrossim subsuite 100 passed, 2 skipped.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(metrics): collapse MicroSSIM.fit per-slice pooling into get_…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T01:30:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "424343f5e1c9f34921936b037863479c91072b28",
          "body": "Frozen-fixture parity against juglab/microssim@8bccb17d. Validates that\nthe cubic port produces numerically identical results to upstream within\n1e-3 on per-slice scores, with ranking preserved (Spearman >= 0.99).\n\n- _generate_golden.py: offline generator that runs once against the\n  pinned upstream\n[…]\n0.2, scipy\n1.17.0, skimage 0.26.0) against upstream goldens generated under their\nrespective pinned versions — all six tests pass.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(metrics): add upstream MicroSSIM parity fixture + tests",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T01:01:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f85b248f6eb7e08e4885cd354b8488ed657e6591",
          "body": "…mp 0.7.0a4\n\nPublic API completes the juglab/microssim port:\n\n- MicroSSIM: __init__ raises if ri_factor is provided without all three\n  norm params (matches micro_ssim.py:270-279). fit() validates type\n  equality, list length, shape, and ndim ∈ {2,3} up-front (matches\n  micro_ssim.py:335-352), then \n[…]\nD pair. Do NOT call score() on a 3-D stack (upstream raises).\n\nBumps cubic to 0.7.0a4 (pyproject reads __version__ via attribute).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add MicroSSIM/MicroMS3IM classes + convenience fns; bu…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T01:00:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9c3c554d693cdfdad77545d9a9e0b3e5051a4c2a",
          "body": "…ompatible)\n\nStandalone multi-scale SSIM primitive matching torchmetrics'\nMultiScaleStructuralSimilarityIndexMeasure exactly. Does NOT reuse\ncompute_ssim_elements — the torchmetrics path uses POPULATION variance\n(no cov_norm), clamps vx/vy >= 0, and applies explicit reflect-pad\n+ valid conv at the b\n[…]\nses upstream's torchmetrics+torch runtime dep for the MicroMS3IM\nscoring path (other VisCy apps still bring them in transitively).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add general-purpose ms_ssim (Wang 2003, torchmetrics-c…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T00:59:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a0566115573c73cef065e579abd8b7ca3b4e2f46",
          "body": "Replaces upstream microssim's scipy.optimize.minimize (BFGS) call at\nri_factor.py:28-35 — drops scipy.optimize from the cubic runtime path.\n\n- get_ri_factor(elements): 1-D bracket+bisection on the analytical\n  mean-pixel derivative dS/dα. Bracket expands from α=1 (where the\n  MicroSSIM-normalized op\n[…]\n\n  drifts the RI factor by ~0.012 on representative fixtures.\n\nSciPy parity verified to 1e-5 against scipy.optimize.minimize BFGS.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add RI-factor solver via bracket + bisection on dS/dα",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T00:59:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5f91e6baa24fe48affbd0047486130cdacc87498",
          "body": "…e_min_max)\n\nPort of microssim/image_processing/{linearize.py, micro_ssim_normalization.py}:\n\n- linearize_list: ravel + concatenate a list of arrays (supports ragged\n  shapes). Pass-through for ndarray inputs.\n- compute_norm_parameters: np.percentile-based bg offset estimation and\n  max-val derivati\n[…]\ntream).\n\nPlain NumPy ops throughout. No cubic.cuda.ascupy — duck typing carries\nthe device through for both NumPy and CuPy arrays.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add image_processing helpers (linearize_list, normaliz…",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T00:59:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "16013d498dc5d99dd2c4a980ef57569367f7ed8b",
          "body": "Foundation of the cubic-side port of juglab/microssim@8bccb17d. Device-\nagnostic SSIM element computation (means, variances, covariance) with\ntwo filter modes matching upstream:\n\n- gaussian_weights=False (default, the RI-fit path per ri_factor.py:89):\n  uniform_filter via cubic.scipy.ndimage with wi\n[…]\nrrors (no asserts; assertions are stripped under -O) for\nndim, shape, win_size oddness, spatial extent, and data_range finiteness.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add compute_ssim_elements with batched gaussian filter",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-05-22T00:58:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d3029324ac3a10d5923b832d62cb36c5ca3013e4",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a3",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-04-03T00:43:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2c071ba00fe43d9af0af417cfb6824b16f926e64",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: add executed outputs to split comparison notebook",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-04-02T22:19:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "264d646d0d0b990a6c66ce528fa0c5afc2b19c63",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-04-02T21:55:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "207b6bd0c2caf8d499aa92446a87eda146b8efb4",
          "body": "* docs: add commit workflow to AGENTS.md and simplify CLAUDE.md\n\nAdd a procedural commit workflow checklist (list → group by concept →\nplan N commits → execute) to prevent grouping changes by workflow step.\nSimplify CLAUDE.md to just reference AGENTS.md.\n\nCo-Authored-By: Claude Opus 4.6 (1M context)\n[…]\nOpus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics): add binomial splitting for single-image FRC/FSC (#40)",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-04-02T21:54:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8883d9c3f7f84b7933b084b53584c6f3fc07f7f6",
          "body": "* fix: add targeted type-ignore comments for pre-existing mypy errors\n\nNow that ignore_errors is removed (c216751), mypy catches 29\npre-existing type issues across 4 files. Add targeted # type: ignore\ncomments with error codes for each, so mypy enforcement is active\nwithout requiring a full type-ann\n[…]\nOpus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: address code quality issues",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-23T19:42:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7bff83a8f61d57d30d75625184f7fee34e189f0f",
          "body": "Scripts in examples/scripts/ are auto-generated from notebooks by CI.\nThey should not be linted — the source notebooks are the linting target.",
          "is_bot": false,
          "headline": "chore: exclude auto-generated scripts from ruff linting",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-12T20:47:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3547243ff3faf6b445234aa4b51e0eb3f08c34d",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 0.7.0a2",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-12T20:40:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "98c86fe58fdd4b1b91e36fea18a534be5d68dde3",
          "body": null,
          "is_bot": true,
          "headline": "chore: auto-generate scripts from notebooks",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-03-12T20:30:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa41e7ab078b7bc73f5a2a1a26ba2afa7ac3feec",
          "body": "* feat(examples): add 3D monolayer segmentation notebook\n\nAdd notebook reproducing CellProfiler 3D monolayer segmentation\n(BBBC034v1, Thirstrup et al. 2018) using cubic. Includes nuclei\nand cell segmentation pipelines with AP evaluation against\nCellProfiler reference labels.\n\nData auto-downloaded vi\n[…]\nOpus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(examples): add segmentation & feature extraction examples (#33)",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-12T20:29:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8c97f84bf242f126607feb0e399632d71f07e321",
          "body": "Remove internal implementation details, debugging comparison tables,\nand development notes. Keep only user-facing API docs, quick start\nexamples, and method selection guidance.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: simplify spectral and bandlimited READMEs for public release",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-10T20:54:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7b7774aff6b923a6bd0d9350fbb9f10f2c4783f5",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: set version to 0.7.0a1 to match alpha release tag",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-10T20:47:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "adc190a5f949e9183e951ac9b421b9c74bfff4c0",
          "body": "* feat(metrics/frc): sketch decorrelartion analysis implementation\n\n* feat(metrics): add masking to skimage image metrics\n\n* feat(metrics/frc): WIP add histogram backend for FRC/FSC\n\n* chore: add claude.md\n\n* refactor(metrics/frc): align mask and hist FRC back-ends\n\n* fix(metrics/frc): expose backen\n[…]\nd-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(metrics/spectral): DCR, histogram FSC, band-limited metrics (#32)",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-03-10T20:40:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9795e2b40c5bd776832065b0e4ed21fb4fb1021b",
          "body": null,
          "is_bot": false,
          "headline": "chore: gitignore macos files",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-02-12T19:20:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "84f4a1e5d85f1b12302b924377a71c465f89b15c",
          "body": "Fixes inherited bug from miplib where first_guess crashes with\nIndexError when FRC/FSC correlation stays above the threshold.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(frc): return nan when correlation never crosses threshold",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-02-12T19:12:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "53d1d4a9c50df5a854e754c8af6acb81d39ba579",
          "body": null,
          "is_bot": false,
          "headline": "chore: update year in license",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-02-12T02:31:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "028b32bad4843e46cf36bb61bff054a9e25c43d5",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.6.0 and add PyPI install to readme",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-02-12T02:28:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b1e55fb82a7d18bed7c24070fc773943c918b5fa",
          "body": null,
          "is_bot": false,
          "headline": "fix(workflows): combine ruff and testing into one workflow",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-01-06T19:22:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68771723cd4a709d98217f43ffb50dc2d040fff5",
          "body": null,
          "is_bot": false,
          "headline": "chore(workflows): use uv for ruff workflows",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-01-06T19:12:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b357342a4cde60e7a9b5a61bbaaf0993e564bb3",
          "body": null,
          "is_bot": false,
          "headline": "chore(workflows): use uv to build the package",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-01-06T19:07:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58e899bfca2ddc97e20d37ba2c0fee508b9e7858",
          "body": null,
          "is_bot": false,
          "headline": "chore: add release.yml",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2026-01-06T18:29:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15e92b703b862fb6a805e1dc81f23c9b046d5d60",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): add links to cupy, cucim installation",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2025-11-14T01:19:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3755083bab78759bd496a65487d818513897618",
          "body": null,
          "is_bot": false,
          "headline": "fix(cucim): add GPU io module to match skimage.io",
          "author_name": "Alexandr Kalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2025-09-10T04:10:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0882df3df36f5f3ec8f6f59e0138618978f02b5d",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): update description",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2025-07-22T21:22:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "84372dbc4b251fb6c0fb330aac29059cc7403ca0",
          "body": null,
          "is_bot": false,
          "headline": "style(examples/deconv): sort imports",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2025-07-22T19:59:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fdb183787ace610f8a0649ce47a8a6896379eb2",
          "body": null,
          "is_bot": false,
          "headline": "fix(examples/deconv): fix typo",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2025-07-22T19:59:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1fac78f43c1d3b35715a7513d159b94f6e985244",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): fix install; add ICCV citation",
          "author_name": "alxndrkalinin",
          "author_login": "alxndrkalinin",
          "committed_at": "2025-07-22T19:59:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 17,
      "commits_last_year": 95,
      "latest_release_at": "2026-07-24T01:07:59Z",
      "latest_release_tag": "v0.8.0",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 14,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 6.5
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "cubic",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "Development Status :: 4 - Beta",
            "Intended Audience :: Developers",
            "Intended Audience :: Science/Research",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
            "Programming Language :: Python",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Topic :: Software Development :: Libraries",
            "Topic :: Software Development :: Libraries :: Python Modules"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/cubic/",
          "is_deprecated": false,
          "latest_version": "0.8.0",
          "repository_url": "https://github.com/alxndrkalinin/cubic",
          "versions_count": 18,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2021-10-17T15:46:40.084908Z",
          "latest_published_at": "2026-07-24T04:47:04.361453Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 31,
      "watchers": 2,
      "fork_history": {
        "days": [
          {
            "date": "2022-10-26",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 1
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples",
        "notebooks"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 63861,
      "source_files_sampled": 93,
      "oversized_source_files": 1,
      "agent_instruction_files": [
        "AGENTS.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 9016
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [
          {
            "name": "pillow",
            "direct": false,
            "version": "12.1.1",
            "severity": "critical",
            "ecosystem": "pypi",
            "cvss_score": 9.1,
            "advisory_ids": [
              "GHSA-45hq-cxwh-f6vc",
              "GHSA-4x4j-2g7c-83w6",
              "GHSA-5x94-69rx-g8h2",
              "GHSA-5xmw-vc9v-4wf2",
              "GHSA-62p4-gmf7-7g93",
              "GHSA-6r8x-57c9-28j4",
              "GHSA-8v84-f9pq-wr9x",
              "GHSA-9hw9-ch79-4vh6",
              "GHSA-fj7v-r99m-22gq",
              "GHSA-jjj6-mw9f-p565"
            ],
            "fixed_version": "12.3.0",
            "advisory_count": 36,
            "oldest_advisory_days": 101
          },
          {
            "name": "jupyterlab",
            "direct": false,
            "version": "4.5.7",
            "severity": "high",
            "ecosystem": "pypi",
            "cvss_score": 7.6,
            "advisory_ids": [
              "GHSA-89vp-jrxv-24w8",
              "GHSA-gx64-gj6p-pc4c",
              "GHSA-h5v5-8746-g7mm",
              "GHSA-pppj-hq3g-57pj",
              "GHSA-vmhf-c436-hxj4",
              "GHSA-whvh-wf3x-g77j"
            ],
            "fixed_version": "4.6.2",
            "advisory_count": 6,
            "oldest_advisory_days": 34
          },
          {
            "name": "mistune",
            "direct": false,
            "version": "3.2.1",
            "severity": "high",
            "ecosystem": "pypi",
            "cvss_score": 7.5,
            "advisory_ids": [
              "GHSA-2hm2-hc3v-44h9",
              "GHSA-4j32-57v6-6g45",
              "GHSA-8c25-4j27-2rv3",
              "GHSA-8mpj-m6qm-5qr8",
              "GHSA-c8j7-8cv4-2xmq",
              "GHSA-ffq3-xpv3-j92q",
              "GHSA-g97x-gvcm-x72h",
              "GHSA-qcq2-496w-v96p",
              "GHSA-qfrw-5rxm-mhh2",
              "GHSA-r4rv-85jg-w4mf"
            ],
            "fixed_version": "3.3.0",
            "advisory_count": 20,
            "oldest_advisory_days": 15
          },
          {
            "name": "torch",
            "direct": false,
            "version": "2.10.0",
            "severity": "high",
            "ecosystem": "pypi",
            "cvss_score": 7.8,
            "advisory_ids": [
              "GHSA-rrmf-rvhw-rf47",
              "PYSEC-2026-139"
            ],
            "fixed_version": "2.13.0",
            "advisory_count": 2,
            "oldest_advisory_days": 479
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.6.3",
            "severity": "high",
            "ecosystem": "pypi",
            "cvss_score": 7.5,
            "advisory_ids": [
              "GHSA-mf9v-mfxr-j63j",
              "GHSA-qccp-gfcp-xxvc",
              "PYSEC-2026-141",
              "PYSEC-2026-142"
            ],
            "fixed_version": "2.7.0",
            "advisory_count": 4,
            "oldest_advisory_days": 73
          },
          {
            "name": "bleach",
            "direct": false,
            "version": "6.3.0",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 6.1,
            "advisory_ids": [
              "GHSA-8rfp-98v4-mmr6",
              "GHSA-g75f-g53v-794x",
              "GHSA-gj48-438w-jh9v"
            ],
            "fixed_version": "6.4.0",
            "advisory_count": 3,
            "oldest_advisory_days": 37
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.11",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 5.3,
            "advisory_ids": [
              "GHSA-65pc-fj4g-8rjx",
              "PYSEC-2026-215"
            ],
            "fixed_version": "3.15",
            "advisory_count": 2,
            "oldest_advisory_days": 65
          },
          {
            "name": "jupyter-server",
            "direct": false,
            "version": "2.18.2",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 5.4,
            "advisory_ids": [
              "GHSA-fcw5-x6j4-ccmp",
              "PYSEC-2026-366"
            ],
            "fixed_version": "2.20.0",
            "advisory_count": 2,
            "oldest_advisory_days": 35
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "9.0.2",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 6.8,
            "advisory_ids": [
              "GHSA-6w46-j5rx-g56g",
              "PYSEC-2026-1845"
            ],
            "fixed_version": "9.0.3",
            "advisory_count": 2,
            "oldest_advisory_days": 182
          },
          {
            "name": "requests",
            "direct": false,
            "version": "2.32.5",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 5.5,
            "advisory_ids": [
              "GHSA-gc5v-m9x4-r6x2",
              "PYSEC-2026-2275"
            ],
            "fixed_version": "2.33.0",
            "advisory_count": 2,
            "oldest_advisory_days": 120
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": "82.0.0",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 6.1,
            "advisory_ids": [
              "GHSA-h35f-9h28-mq5c",
              "PYSEC-2026-3447"
            ],
            "fixed_version": "83.0.0",
            "advisory_count": 2,
            "oldest_advisory_days": 15
          },
          {
            "name": "tornado",
            "direct": false,
            "version": "6.5.6",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": 5.9,
            "advisory_ids": [
              "GHSA-pw6j-qg29-8w7f"
            ],
            "fixed_version": "6.5.7",
            "advisory_count": 1,
            "oldest_advisory_days": 38
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.19.2",
            "severity": "low",
            "ecosystem": "pypi",
            "cvss_score": 3.3,
            "advisory_ids": [
              "GHSA-5239-wwwm-4pmq",
              "PYSEC-2026-2987"
            ],
            "fixed_version": "2.20.0",
            "advisory_count": 2,
            "oldest_advisory_days": 123
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "low": 1,
          "high": 4,
          "critical": 1,
          "moderate": 7
        },
        "advisory_count": 84,
        "affected_count": 13,
        "assessed_count": 166,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 1,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "numpy",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.20.0"
        },
        {
          "name": "scikit-image",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.16.1"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "numpy",
            "direct": true,
            "version": "2.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "scikit-image",
            "direct": true,
            "version": "0.25.2",
            "ecosystem": "pypi"
          },
          {
            "name": "anyio",
            "direct": false,
            "version": "4.13.0",
            "ecosystem": "pypi"
          },
          {
            "name": "appnope",
            "direct": false,
            "version": "0.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "argon2-cffi",
            "direct": false,
            "version": "25.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "argon2-cffi-bindings",
            "direct": false,
            "version": "25.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "arrow",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "asttokens",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "async-lru",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "attrs",
            "direct": false,
            "version": "26.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "beautifulsoup4",
            "direct": false,
            "version": "4.14.3",
            "ecosystem": "pypi"
          },
          {
            "name": "bleach",
            "direct": false,
            "version": "6.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "cellpose",
            "direct": false,
            "version": "4.2.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2026.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "cffi",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "cfgv",
            "direct": false,
            "version": "3.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "comm",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "contourpy",
            "direct": false,
            "version": "1.3.2",
            "ecosystem": "pypi"
          },
          {
            "name": "cubic",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "cuda-bindings",
            "direct": false,
            "version": "12.9.4",
            "ecosystem": "pypi"
          },
          {
            "name": "cuda-pathfinder",
            "direct": false,
            "version": "1.3.4",
            "ecosystem": "pypi"
          },
          {
            "name": "cycler",
            "direct": false,
            "version": "0.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "debugpy",
            "direct": false,
            "version": "1.8.20",
            "ecosystem": "pypi"
          },
          {
            "name": "decorator",
            "direct": false,
            "version": "5.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "defusedxml",
            "direct": false,
            "version": "0.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "distlib",
            "direct": false,
            "version": "0.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "exceptiongroup",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "executing",
            "direct": false,
            "version": "2.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fastjsonschema",
            "direct": false,
            "version": "2.21.2",
            "ecosystem": "pypi"
          },
          {
            "name": "fastremap",
            "direct": false,
            "version": "1.17.7",
            "ecosystem": "pypi"
          },
          {
            "name": "filelock",
            "direct": false,
            "version": "3.21.0",
            "ecosystem": "pypi"
          },
          {
            "name": "fill-voids",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fonttools",
            "direct": false,
            "version": "4.62.0",
            "ecosystem": "pypi"
          },
          {
            "name": "fqdn",
            "direct": false,
            "version": "1.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fsspec",
            "direct": false,
            "version": "2026.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "h11",
            "direct": false,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "httpcore",
            "direct": false,
            "version": "1.0.9",
            "ecosystem": "pypi"
          },
          {
            "name": "httpx",
            "direct": false,
            "version": "0.28.1",
            "ecosystem": "pypi"
          },
          {
            "name": "identify",
            "direct": false,
            "version": "2.6.16",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.11",
            "ecosystem": "pypi"
          },
          {
            "name": "imagecodecs",
            "direct": false,
            "version": "2025.3.30",
            "ecosystem": "pypi"
          },
          {
            "name": "imageio",
            "direct": false,
            "version": "2.37.2",
            "ecosystem": "pypi"
          },
          {
            "name": "iniconfig",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ipykernel",
            "direct": false,
            "version": "7.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ipython",
            "direct": false,
            "version": "8.39.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ipython-pygments-lexers",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "ipywidgets",
            "direct": false,
            "version": "8.1.8",
            "ecosystem": "pypi"
          },
          {
            "name": "isoduration",
            "direct": false,
            "version": "20.11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jedi",
            "direct": false,
            "version": "0.20.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": false,
            "version": "3.1.6",
            "ecosystem": "pypi"
          },
          {
            "name": "json5",
            "direct": false,
            "version": "0.14.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonpointer",
            "direct": false,
            "version": "3.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonschema",
            "direct": false,
            "version": "4.26.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonschema-specifications",
            "direct": false,
            "version": "2025.9.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-client",
            "direct": false,
            "version": "8.8.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-console",
            "direct": false,
            "version": "6.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-core",
            "direct": false,
            "version": "5.9.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-events",
            "direct": false,
            "version": "0.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-lsp",
            "direct": false,
            "version": "2.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-server",
            "direct": false,
            "version": "2.18.2",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-server-terminals",
            "direct": false,
            "version": "0.5.4",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab",
            "direct": false,
            "version": "4.5.7",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab-pygments",
            "direct": false,
            "version": "0.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab-server",
            "direct": false,
            "version": "2.28.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab-widgets",
            "direct": false,
            "version": "3.0.16",
            "ecosystem": "pypi"
          },
          {
            "name": "kiwisolver",
            "direct": false,
            "version": "1.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "lark",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "lazy-loader",
            "direct": false,
            "version": "0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "librt",
            "direct": false,
            "version": "0.8.0",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "matplotlib",
            "direct": false,
            "version": "3.10.8",
            "ecosystem": "pypi"
          },
          {
            "name": "matplotlib-inline",
            "direct": false,
            "version": "0.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mistune",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mpmath",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy",
            "direct": false,
            "version": "1.19.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy-extensions",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "natsort",
            "direct": false,
            "version": "8.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "nbclient",
            "direct": false,
            "version": "0.10.4",
            "ecosystem": "pypi"
          },
          {
            "name": "nbconvert",
            "direct": false,
            "version": "7.17.1",
            "ecosystem": "pypi"
          },
          {
            "name": "nbformat",
            "direct": false,
            "version": "5.10.4",
            "ecosystem": "pypi"
          },
          {
            "name": "nest-asyncio",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "networkx",
            "direct": false,
            "version": "3.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "nodeenv",
            "direct": false,
            "version": "1.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "notebook",
            "direct": false,
            "version": "7.5.6",
            "ecosystem": "pypi"
          },
          {
            "name": "notebook-shim",
            "direct": false,
            "version": "0.2.4",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cublas-cu12",
            "direct": false,
            "version": "12.8.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cuda-cupti-cu12",
            "direct": false,
            "version": "12.8.90",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cuda-nvrtc-cu12",
            "direct": false,
            "version": "12.8.93",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cuda-runtime-cu12",
            "direct": false,
            "version": "12.8.90",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cudnn-cu12",
            "direct": false,
            "version": "9.10.2.21",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cufft-cu12",
            "direct": false,
            "version": "11.3.3.83",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cufile-cu12",
            "direct": false,
            "version": "1.13.1.3",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-curand-cu12",
            "direct": false,
            "version": "10.3.9.90",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cusolver-cu12",
            "direct": false,
            "version": "11.7.3.90",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cusparse-cu12",
            "direct": false,
            "version": "12.5.8.93",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-cusparselt-cu12",
            "direct": false,
            "version": "0.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-nccl-cu12",
            "direct": false,
            "version": "2.27.5",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-nvjitlink-cu12",
            "direct": false,
            "version": "12.8.93",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-nvshmem-cu12",
            "direct": false,
            "version": "3.4.5",
            "ecosystem": "pypi"
          },
          {
            "name": "nvidia-nvtx-cu12",
            "direct": false,
            "version": "12.8.90",
            "ecosystem": "pypi"
          },
          {
            "name": "opencv-python-headless",
            "direct": false,
            "version": "4.13.0.92",
            "ecosystem": "pypi"
          },
          {
            "name": "overrides",
            "direct": false,
            "version": "7.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "26.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pandocfilters",
            "direct": false,
            "version": "1.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "parso",
            "direct": false,
            "version": "0.8.7",
            "ecosystem": "pypi"
          },
          {
            "name": "pathspec",
            "direct": false,
            "version": "1.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "pexpect",
            "direct": false,
            "version": "4.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pillow",
            "direct": false,
            "version": "12.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "platformdirs",
            "direct": false,
            "version": "4.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pluggy",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pooch",
            "direct": false,
            "version": "1.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pre-commit",
            "direct": false,
            "version": "4.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "prometheus-client",
            "direct": false,
            "version": "0.25.0",
            "ecosystem": "pypi"
          },
          {
            "name": "prompt-toolkit",
            "direct": false,
            "version": "3.0.52",
            "ecosystem": "pypi"
          },
          {
            "name": "psutil",
            "direct": false,
            "version": "7.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "ptyprocess",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pure-eval",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pycparser",
            "direct": false,
            "version": "3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.19.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pyparsing",
            "direct": false,
            "version": "3.3.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "9.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dateutil",
            "direct": false,
            "version": "2.9.0.post0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-json-logger",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pywinpty",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyzmq",
            "direct": false,
            "version": "27.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "referencing",
            "direct": false,
            "version": "0.37.0",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": false,
            "version": "2.32.5",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3339-validator",
            "direct": false,
            "version": "0.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3986-validator",
            "direct": false,
            "version": "0.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3987-syntax",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "roifile",
            "direct": false,
            "version": "2025.12.12",
            "ecosystem": "pypi"
          },
          {
            "name": "rpds-py",
            "direct": false,
            "version": "0.30.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ruff",
            "direct": false,
            "version": "0.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "scipy",
            "direct": false,
            "version": "1.15.3",
            "ecosystem": "pypi"
          },
          {
            "name": "segment-anything",
            "direct": false,
            "version": "1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "send2trash",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": "82.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "soupsieve",
            "direct": false,
            "version": "2.8.4",
            "ecosystem": "pypi"
          },
          {
            "name": "stack-data",
            "direct": false,
            "version": "0.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "sympy",
            "direct": false,
            "version": "1.14.0",
            "ecosystem": "pypi"
          },
          {
            "name": "terminado",
            "direct": false,
            "version": "0.18.1",
            "ecosystem": "pypi"
          },
          {
            "name": "tifffile",
            "direct": false,
            "version": "2025.5.10",
            "ecosystem": "pypi"
          },
          {
            "name": "tinycss2",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli",
            "direct": false,
            "version": "2.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "torch",
            "direct": false,
            "version": "2.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "torchvision",
            "direct": false,
            "version": "0.25.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tornado",
            "direct": false,
            "version": "6.5.6",
            "ecosystem": "pypi"
          },
          {
            "name": "tqdm",
            "direct": false,
            "version": "4.67.3",
            "ecosystem": "pypi"
          },
          {
            "name": "traitlets",
            "direct": false,
            "version": "5.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "trimesh",
            "direct": false,
            "version": "4.11.2",
            "ecosystem": "pypi"
          },
          {
            "name": "triton",
            "direct": false,
            "version": "3.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tzdata",
            "direct": false,
            "version": "2026.2",
            "ecosystem": "pypi"
          },
          {
            "name": "uri-template",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "virtualenv",
            "direct": false,
            "version": "20.36.1",
            "ecosystem": "pypi"
          },
          {
            "name": "wcwidth",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "webcolors",
            "direct": false,
            "version": "25.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "webencodings",
            "direct": false,
            "version": "0.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "websocket-client",
            "direct": false,
            "version": "1.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "widgetsnbextension",
            "direct": false,
            "version": "4.0.15",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 167,
        "direct_count": 2,
        "indirect_count": 165
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 1,
        "merged_prs": 44,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 5,
        "closed_unmerged_prs": 2
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "alxndrkalinin",
          "commits": 366,
          "avatar_url": "https://avatars.githubusercontent.com/u/1107762?v=4"
        },
        {
          "type": "User",
          "login": "SourceryAI",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/60611498?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.997
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "lint-format.yml",
        "notebooks.yml",
        "release.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": true
    },
    "security_signals": {
      "lockfiles": [
        "uv.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "4 out of 4 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/12 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 4 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "48 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "e354584402a0cbc16d2b2130c8e8bdd14baeb39b",
        "ran_at": "2026-07-24T04:48:13Z",
        "aggregate_score": 3.8,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-24T04:47:09Z",
      "oldest_open_prs": [
        {
          "number": 34,
          "created_at": "2026-03-12T22:35:17Z",
          "last_comment_at": "2026-03-18T17:08:22Z",
          "last_comment_author": "alxndrkalinin"
        }
      ],
      "last_merged_pr_at": "2026-06-19T05:36:14Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/alxndrkalinin/cubic",
    "host": "github.com",
    "name": "cubic",
    "owner": "alxndrkalinin"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 64,
      "inputs": {
        "security": 50,
        "vitality": 84,
        "community": 36,
        "governance": 63,
        "engineering": 82
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 84,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "commits_last_year": 95,
              "human_commit_share": 0.93,
              "days_since_last_push": 0,
              "active_weeks_last_year": 14
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "14/52 weeks with commits",
                "points": 9.7,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 14
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "95 commits in the last year",
                "points": 17.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 95
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 17,
              "latest_release_tag": "v0.8.0",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 6.5
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "17 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 17
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~6.5 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 6.5
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 0,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 0 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 36,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 24,
            "inputs": {
              "forks": 1,
              "stars": 31,
              "watchers": 2,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "31 stars",
                "points": 24,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 31
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "2 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 63,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 22,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.997
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0.1,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 4 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 83,
            "inputs": {
              "merged_prs": 44,
              "open_issues": 0,
              "closed_issues": 5,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 2
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "44/46 decided PRs merged",
                "points": 36.6,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 44,
                      "decided": 46
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/12 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 64,
            "inputs": {
              "followers": 177,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "alxndrkalinin",
              "public_repos": 107,
              "account_age_days": 5404
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "177 followers of alxndrkalinin",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 177,
                      "login": "alxndrkalinin"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "107 public repos, account ~14 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 107
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 14
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "cubic"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "18 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 18
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 82,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "excellent",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 94,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": true
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "3 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 16,
                "status": "met",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 9.6,
                "status": "met",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "4 out of 4 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://doi.org/10.1109/ICCVW69036.2025.00608",
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://doi.org/10.1109/ICCVW69036.2025.00608",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 50,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 38,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 3.8
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "4 out of 4 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/12 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 4 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "48 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 166 resolved dependencies against OSV; 1 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories",
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 166
                }
              },
              {
                "code": "advisories_unassessed",
                "params": {
                  "count": 1
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 84,
              "affected_packages": 13,
              "assessed_packages": 166,
              "unassessed_packages": 1,
              "affected_by_severity": "critical 1, high 4, moderate 7, low 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 166,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 3
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 61,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                "AGENTS.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 9016
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md, CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "93 of 93 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 93,
                      "sampled": 93
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 53,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0.76,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 11,
                "status": "met",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "76 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 76,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 63861,
              "source_files_sampled": 93,
              "oversized_source_files": 1
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "1/93 source files over 60KB",
                "points": 54.4,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 93,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples",
                "notebooks"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples, notebooks",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples, notebooks"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "deps.dev does not index pypi:cubic@0.8.0; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-24T04:48:26.826596Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/alxndrkalinin/cubic.svg",
  "full_name": "alxndrkalinin/cubic",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Оцінки — це сигнали, а не гарантії. Вони відображають публічно видимі практики на GitHub — це не аудит коду й не гарантія безпеки.

Відсутні дані виключаються, а ваги перенормовуються — нуль за відсутність ніколи не ставиться. Методологія версіонована й відкрита: метрики v1.13.0, схема v0.27.0 — повна методологія · вікі метрик.

Як окремий результат виглядає на тлі всього реєстру: сукупна статистикаPyPI.