Score описывает состояние репозитория по доступным признакам. Рядом мы показываем охват данных: насколько широко удалось применить методику к этому проекту.
Читаем доступные данные SourceCraft: код, активность, документацию, CI, задачи и безопасность.
Нормализуем метрики и собираем балл категории от 0 до 100. Категория участвует, если доступно не менее 50% веса её метрик.
Берём взвешенное среднее оценённых категорий. Категория без данных не превращается в ноль.
Считаем категории, для которых хватило данных. Если таких нет, Score не показываем.
D показывает, какая часть категорий методики вошла в расчёт Score.
Охват данных — доля суммарного веса категорий, для которых хватило данных. Например, если оценены код (21%), активность (18%) и документация (17%), показатель равен 56%.
Нажмите на категорию: так меняется охват оценки. Это учебный пример, не анализ проекта.
В Score входят только выбранные здесь категории. Их значения могут быть высокими или низкими — процент выше этого не показывает.
Сравнивайте Score внимательнее, если охват данных у проектов сильно различается: оценки могут опираться на разные наборы категорий.
Неизвестная метрика не получает ноль. Если данных по категории недостаточно, её исключаем из Score — и охват данных снижается.
Подтверждённый факт может дать ноль. Например, если полное дерево репозитория доказывает отсутствие SourceCraft CI, категория CI оценивается в 0.
Здесь можно проверить метрики, ограничения и точные формулы методики.
Неизвестное значение помечаем «нет данных» — оно не становится нулём.
Это базовый балл. После поправок и ограничений получаем итоговый Sc.
Порог участия: ≥ 50%. При меньшем охвате категория получает статус «нет данных». Доказанное отсутствие CI — отдельное исключение.
В расчёте участвуют только оценённые категории. Их итоговый балл — от 0 до 100.
Показатель говорит, какая часть категорий методики участвовала в расчёте.
| Метрика | Единица | Вес | Нормализация |
|---|---|---|---|
| Открытые уязвимости, взвешенные по критичности security.open_weighted | балл риска | 5 | линейно: 30 → 0, 0 → 1 |
| Доля исправленных findings за 90 дней security.resolved_ratio_90d | — | 2 | доля 0..1 |
| Открытые секреты в коде security.open_secrets | шт. | 3 | ступени: ≥0 → 1, ≥1 → 0 |
| Свежий скан безопасности (≤ 30 дней) security.scan_fresh | — | 1 | да → 1, нет → 0 |
| Метрика | Единица | Вес | Нормализация |
|---|---|---|---|
| Плотность TODO/FIXME/HACK на 1000 строк кода code.todo_density | на 1000 строк | 3 | линейно: 20 → 0, 1 → 1 |
| Доля TODO старше 6 месяцев code.todo_old_share | — | 2 | линейно: 1 → 0, 0 → 1 |
| Тесты: наличие и доля тестового кода code.tests_ratio | кода в тестах | 3 | ступени: ≥0 → 0, ≥0.0001 → 0.5, ≥0.05 → 0.75, ≥0.15 → 1 |
| Зафиксированные зависимости (lockfile) при наличии манифеста code.lockfile | — | 1 | да → 1, нет → 0 |
| Доля крупных и бинарных файлов code.heavy_files_share | — | 1 | линейно: 0.3 → 0, 0.02 → 1 |
| Линтеры, форматтеры, editorconfig code.quality_tooling | инструментов | 1 | ступени: ≥0 → 0, ≥1 → 0.7, ≥2 → 1 |
| Метрика | Единица | Вес | Нормализация |
|---|---|---|---|
| Давность последнего осмысленного коммита activity.days_since_last_commit | дней назад | 3 | exp(−дни/90) — свежесть |
| Осмысленные коммиты за 90 дней activity.meaningful_commits_90d | шт. | 2 | 1 − exp(−x/30) — убывающая отдача |
| Живые авторы за год (без ботов) activity.human_authors_365d | чел. | 2 | 1 − exp(−x/3) — убывающая отдача |
| Bus factor (авторов, покрывающих 50% коммитов за год) activity.bus_factor | чел. | 2 | ступени: ≥0 → 0, ≥1 → 0.2, ≥2 → 0.6, ≥3 → 1 |
| Влитые PR за 90 дней activity.merged_prs_90d | шт. | 1 | 1 − exp(−x/10) — убывающая отдача |
| Разных авторов влитых PR за год activity.pr_authors_365d | чел. | 1 | 1 − exp(−x/2) — убывающая отдача |
| Давность последнего релиза или тега activity.release_recency_days | дней назад | 1 | exp(−дни/180) — свежесть |
| Метрика | Единица | Вес | Нормализация |
|---|---|---|---|
| README: наличие, объём и ключевые разделы docs.readme_quality | — | 4 | доля 0..1 |
| Лицензия (распознанный SPDX) docs.license | — | 2 | доля 0..1 |
| CONTRIBUTING, CODEOWNERS, CHANGELOG, SECURITY.md docs.practices | из 4 | 2 | линейно: 0 → 0, 3 → 1 |
| Описание репозитория заполнено в SourceCraft docs.description | — | 1 | да → 1, нет → 0 |
| Правила ревью и политики веток docs.sourcecraft_policies | из 2 | 2 | ступени: ≥0 → 0, ≥1 → 0.6, ≥2 → 1 |
| Инструкция запуска и сборки docs.run_instructions | — | 2 | да → 1, нет → 0 |
| Метрика | Единица | Вес | Нормализация |
|---|---|---|---|
| Есть конфигурация CI (.sourcecraft/ci.yaml) ci.config_present | — | 3 | да → 1, нет → 0 |
| Успешные прогоны среди последних 30 (с весом по свежести) ci.success_rate | — | 4 | доля 0..1 |
| Последний прогон успешен ci.last_status_ok | — | 2 | да → 1, нет → 0 |
| Нестабильность: чередование успех/провал ci.flakiness | — | 2 | линейно: 0.6 → 0, 0.1 → 1 |
| Медианная длительность прогона ci.duration_median_min | мин | 1 | линейно: 30 → 0, 5 → 1 |
| CI запускается на pull request ci.pr_trigger | — | 1 | да → 1, нет → 0 |
| Метрика | Единица | Вес | Нормализация |
|---|---|---|---|
| Зависшие открытые issues (без обновления > 60 дней) issues.stale_share | открытых | 3 | линейно: 1 → 0, 0 → 1 |
| Медиана первого ответа или текущего ожидания issues.first_response_median_h | ч | 3 | линейно: 336 → 0, 24 → 1 |
| Медианное время закрытия (за 180 дней) issues.close_median_days | дней | 2 | линейно: 90 → 0, 7 → 1 |
| Закрытые / созданные за 90 дней issues.backlog_trend | — | 2 | линейно: 0.5 → 0, 1.2 → 1 |
| Использование меток, приоритетов, исполнителей issues.triage_usage | issues | 1 | доля 0..1 |
Жёсткий предел применяем только к подтверждённой существенной проблеме. Другие недостатки снижают балл через метрики и появляются в рекомендациях без дополнительного ограничения.
Отсутствие LICENSE влияет на документацию только у открытых репозиториев. Короткий README можно улучшить по рекомендации; предел срабатывает, лишь когда README нет совсем.
При доказанном отсутствии SourceCraft CI категория получает 0 даже без истории запусков. Недоступные метрики запусков остаются помечены как «нет данных».
Прогоны CI старше 90 дней и загруженные результаты сканирования старше 90 дней не подтверждают текущее состояние. Дату загрузки отчёта не принимаем за дату сканирования.
Комментарии AppSec в PR не раскрывают статус и критичность уязвимостей, поэтому не участвуют в оценке безопасности. Пустой репозиторий не оценивается.
Ожидаемый эффект рекомендации показываем, только если после симуляции набор оценённых категорий не изменился.