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

flarum / testing

[READ ONLY] Subtree split of Flarum's backend testing utility library.

PHPMIT★ 0 зірок⑂ 1 форкз січ. 2021 р.Переглянути на GitHub ↗

flarum/testing має індекс здоров’я 52 зі 100, що відповідає смузі «Помірний». Найвищий показник — Sustainability & Governance (75/100), найнижчий — Engineering Quality (27/100). Останнє оновлення — сьогодні. Більшість нещодавньої роботи виконують 2 учасники.

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

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

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

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

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

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

Власність

FlarumОрганізація
798 підписників53 публічні репозиторіїз вер. 2013 р.

За цим репозиторієм стоїть організація — спільна, підзвітна опіка, здатна пережити будь-якого окремого мейнтейнера.

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

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікаціяТеги
Packagistflarum/testingv2.0.0-rc.521 71725101 день томуforumdiscussion

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

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

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

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

Активність розробки

45У зоні ризику
Як обчислюється оцінка
36/36Свіжість push — останній push 0 дн. тому
2.8/36Ритм комітів — 4/52 тижнів із комітами
6.3/18Обсяг комітів — 4 комітів за останній рік
0/10OpenSSF Scorecard: Maintained — 1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Використані вхідні дані
commits_last_year4
human_commit_share0,99
days_since_last_push0
active_weeks_last_year4
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 22 релізів
36/36Свіжість релізів — останній реліз 19 дн. тому
19.8/27Ритм релізів — реліз кожні ~48 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count22
latest_release_tagv2.0.0-rc.5
releases_from_tagsні
days_since_latest_release19
mean_days_between_releases48
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

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

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

38У зоні ризику · 18% загального індексу
Як обчислюється оцінка
0/60Зірки — 0 зірок
0/25Форки — 1 форків
2.7/15Спостерігачі — 4 спостерігачів
Використані вхідні дані
forks1
stars0
watchers4
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
0/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
18/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
6.3/6.3Шаблон PR
Використані вхідні дані
has_readmeні
has_licenseтак
has_contributingтак
has_issue_templateні
has_code_of_conductні
has_pull_request_templateтак
Як обчислюється оцінка
57.8/80Щомісячні завантаження — 21 717 завантажень/місяць у packagist
17.4/20Залежні пакети в реєстрі — залежних пакетів: 411
Використані вхідні дані
packagesflarum/testing
dependents411
ecosystemspackagist
total_downloads391 233
monthly_downloads21 717

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

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

75Добрий · 24% загального індексу
Як обчислюється оцінка
25.2/54Бас-фактор — на 2 контриб’ютор(ів) припадає половина всіх комітів
15.7/22.5Розподіл комітів — головний контриб’ютор — автор 30% комітів
13.5/13.5Широта контриб’юторів — 15 контриб’юторів
10/10OpenSSF Scorecard: Contributors — project has 13 contributing companies or organizations
Використані вхідні дані
bus_factor2
contributors_sampled15
top_contributor_share0,304
Як обчислюється оцінка
0/46.8Вирішення issue — немає issue або даних
35.3/38.3Прийняття PR — злито 12/13 вирішених PR
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Використані вхідні дані
merged_prs12
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs1
Виключено з оцінювання (немає даних або не застосовно): Вирішення issue. Залишкові ваги перенормовано.
Як обчислюється оцінка
30/30Підтримка власника — у власності організації
0/20Верифікований домен
20.9/25Охоплення власника — 798 підписників у flarum
24.6/25Послужний список — 53 публічних репозиторіїв, вік облікового запису ~12 р.
Використані вхідні дані
followers798
owner_typeOrganization
is_verified
owner_loginflarum
public_repos53
account_age_days4 688

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

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 1 пакет(ів) у packagist
35/35Свіжість публікацій — остання публікація 101 дн. тому
20/20Історія версій — 25 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packagesflarum/testing
ecosystemspackagist
any_deprecatedні
min_days_since_publish101

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

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

27Критичний · 20% загального індексу

Інженерні практики

38У зоні ризику
Як обчислюється оцінка
0/24Процеси CI
24/24Наявні тести
0/16Конфігурація лінтера
0/9.6Pre-commit-хуки
6.4/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — немає даних
Використані вхідні дані
has_ciні
has_testsтак
has_editorconfigтак
has_linter_configні
has_precommit_configні
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: CI-Tests. Залишкові ваги перенормовано.

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

10Критичний
Як обчислюється оцінка
0/30README
0/25Каталог документації
0/15Сайт документації / домашня сторінка
10/10Опис репозиторію
0/10Теми
0/10Wiki
Використані вхідні дані
topics
has_wikiні
homepage
has_readmeні
has_docs_dirні
has_descriptionтак

Безпека

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

48У зоні ризику · 16% загального індексу

Стан безпеки

48У зоні ризику
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — немає даних
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 13 contributing companies or organizations
0/10Dangerous-Workflow — немає даних
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
0/7.5Maintained — 1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
0/5Packaging — немає даних
0/5Pinned-Dependencies — немає даних
0/5SAST — no SAST tool detected
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — немає даних
0/7.5Token-Permissions — немає даних
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated12
scorecard_versionv5.5.0
checks_inconclusive6
scorecard_aggregate4,8
Виключено з оцінювання (немає даних або не застосовно): ci_tests, dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions. Залишкові ваги перенормовано.

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

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

39У зоні ризику · 0% загального індексу
Як обчислюється оцінка
0/45Інструкції для агентів — немає CLAUDE.md / AGENTS.md / правил редактора
0/15Машиночитана документація (llms.txt)
33.9/40Читабельна історія комітів — намір зазначено у 63 з 99 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,636
agent_instruction_files
agent_instruction_max_bytes
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
0/11Конфігурація лінтера / форматера
0/11Статична перевірка типів
0/10Відтворюване середовище
2/10Підтверджена практика роботи з агентами — 1 з останніх 100 комітів створено агентом або з його зазначенням
8/8Автоматизоване супроводження — 1 з останніх 100 комітів — автоматичні оновлення залежностей
0/10OpenSSF Scorecard: Pinned-Dependencies — немає даних
Використані вхідні дані
has_nixні
has_testsтак
lockfiles
has_dockerfileні
typed_languageні
bootstrap_files
has_devcontainerні
has_linter_configні
typecheck_configs
agent_commit_share0,01
toolchain_manifests
dependency_bot_commit_share0,01
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Pinned-Dependencies. Залишкові ваги перенормовано.
Як обчислюється оцінка
0/45Типізований код — PHP без конфігурації перевірки типів
55/55Керовані розміри файлів — 0/20 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languagePHP
largest_source_bytes11 108
source_files_sampled20
oversized_source_files0

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

0зірок GitHub
15контриб'юторів
4комітів за останні 12 місяців
0днів від останнього пушу
22релізів
2бас-фактор
0відкритих issue
Packagistпакетних екосистем

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

  • No resolved dependencies carried a version and a supported ecosystem

Докладніше

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

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
н/дCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
10Contributorsproject has 13 contributing companies or organizations
н/дDangerous-Workflowno workflows found
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintained1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
н/дPackagingpackaging workflow not detected
н/дPinned-Dependenciesno dependencies found
0SASTno SAST tool detected
10Security-Policysecurity policy file detected
н/дSigned-Releasesno releases found
н/дToken-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
Прямі залежності 1
РеєстрПакетОбмеження версіїМаніфест
Packagistmockery/mockery^1.5composer.json
Усі залежності 6

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

РеєстрПакетВерсіяЗв'язок
Packagistmockery/mockeryпряма
Packagistext-jsonнепряма
Packagistflarum/coreнепряма
Packagistflarum/testingнепряма
Packagistflarum/testing-testsнепряма
Packagistphpunit/phpunitнепряма
Сповіщення про залежності не оцінено

Звірка сповіщень не відбулася для цього звіту: No resolved dependencies carried a version and a supported ecosystem

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 110,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "PHP": 44230
      },
      "pushed_at": "2026-07-28T13:17:56Z",
      "created_at": "2021-01-07T23:14:42Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-28T13:21:15Z",
      "description": "[READ ONLY] Subtree split of Flarum's backend testing utility library.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "2.x",
      "license_spdx_raw": "MIT",
      "primary_language": "PHP",
      "significant_languages": [
        "PHP"
      ]
    },
    "owner": {
      "blog": "http://flarum.org",
      "name": "Flarum",
      "type": "Organization",
      "login": "flarum",
      "company": null,
      "location": null,
      "followers": 798,
      "avatar_url": "https://avatars.githubusercontent.com/u/5549034?v=4",
      "created_at": "2013-09-26T11:15:45Z",
      "is_verified": null,
      "public_repos": 53,
      "account_age_days": 4688
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.0.0-rc.5",
          "kind": "prerelease",
          "published_at": "2026-07-08T15:55:02Z"
        },
        {
          "tag": "v2.0.0-rc.4",
          "kind": "prerelease",
          "published_at": "2026-06-18T11:59:55Z"
        },
        {
          "tag": "v2.0.0-rc.3",
          "kind": "prerelease",
          "published_at": "2026-06-09T18:54:15Z"
        },
        {
          "tag": "v2.0.0-rc.2",
          "kind": "prerelease",
          "published_at": "2026-06-01T18:18:07Z"
        },
        {
          "tag": "v2.0.0-rc.1",
          "kind": "prerelease",
          "published_at": "2026-04-20T10:16:32Z"
        },
        {
          "tag": "v2.0.0-beta.8.1",
          "kind": "prerelease",
          "published_at": "2026-04-18T21:10:52Z"
        },
        {
          "tag": "v2.0.0-beta.7",
          "kind": "prerelease",
          "published_at": "2026-02-22T17:16:17Z"
        },
        {
          "tag": "v2.0.0-beta.6",
          "kind": "prerelease",
          "published_at": "2026-01-30T09:27:52Z"
        },
        {
          "tag": "v2.0.0-beta.5",
          "kind": "prerelease",
          "published_at": "2025-12-20T22:45:39Z"
        },
        {
          "tag": "v2.0.0-beta.3",
          "kind": "prerelease",
          "published_at": "2025-05-02T08:30:51Z"
        },
        {
          "tag": "v2.0.0-beta.2",
          "kind": "prerelease",
          "published_at": "2025-01-17T09:17:11Z"
        },
        {
          "tag": "v2.0.0-beta.1",
          "kind": "prerelease",
          "published_at": "2024-12-11T17:10:49Z"
        },
        {
          "tag": "v1.8.0",
          "kind": "minor",
          "published_at": "2023-05-20T17:52:21Z"
        },
        {
          "tag": "v1.7.0",
          "kind": "minor",
          "published_at": "2023-03-10T13:44:37Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2022-11-15T11:50:54Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2022-09-13T09:35:02Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2022-08-02T18:05:28Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2022-07-13T12:34:04Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2022-05-12T10:35:33Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2021-06-21T07:44:54Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2021-05-27T08:30:34Z"
        },
        {
          "tag": "v0.1.0-beta.16.1",
          "kind": "prerelease",
          "published_at": "2021-03-11T18:08:10Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "8b4cf12e5a7dbedd7afbc5dc716c9cbc56248442",
          "body": "Binding db.transactions (#4787) means listeners implementing\nShouldHandleEventsAfterCommit are deferred to the surrounding\ntransaction's commit. The integration harness wraps each test in a\ntransaction that is rolled back and never committed, so those callbacks\nwere attached to it and silently disca\n[…]\nat\nreports no applicable pending transactions, so addCallback() runs each\ncallback immediately. db.transactions stays bound and\nConnection::afterCommit() still works, keeping #4787 intact.\n\nRefs #4814",
          "is_bot": false,
          "headline": "Run after-commit callbacks inline in integration tests (#4833)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-07-24T14:13:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d0344b4928a230638f9f3ed64538b0159ffa954a",
          "body": "Unblocks composer install on flarum/testing consumers: the PHPUnit 11.x\nline has no fix for GHSA-qrr6-mg7r-m243 (PKSA-5jz8-6tcw-pbk4), so every\n11.x version is filtered by Composer's advisory check.\n\nPHPUnit 12 requires PHP 8.3+, which matches the 2.x floor. Flarum's own\ntest suites already use PHP 8 attributes exclusively; third-party\nextensions still using @test / @dataProvider docblock annotations will\nneed to migrate.\n\nCloses #4584",
          "is_bot": false,
          "headline": "chore: bump phpunit/phpunit to ^12.5.22 (#4585)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-04-18T09:09:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a06f40dbd3d3a1c51b67a6f1c3faf470d67bd30",
          "body": "* Added support for pgsql's search_path\n\n* Put schema after database name\n\n* Add schema arguments and order 'ask's\n\n* Fixed errors",
          "is_bot": false,
          "headline": "feat: Add support for pgsql's search_path (#4241)",
          "author_name": "Johann Rodríguez",
          "author_login": "johannsa",
          "committed_at": "2026-03-22T20:10:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e224bb24a5a3ba5918a3a9bb40b4399ee25d57c",
          "body": "…atic analysis (#4450)\n\nIntelephense reports \"Undefined method 'getDriverName'\" (and similar)\nbecause the `database` property and `TestCase::database()` return\n`ConnectionInterface`, which doesn't declare concrete `Connection`\nmethods.\n\nKeep `ConnectionInterface` as the actual PHP type so custom con\n[…]\nt add `@var Connection|null` / `@return Connection` PHPDoc\nannotations so Intelephense and PHPStan resolve the concrete methods.\n\nFixes #4432\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(testing): narrow database property/method types via PHPDoc for st…",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2026-03-15T07:01:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e4a4ffbfa107737e26c184bead527aec19ac160d",
          "body": null,
          "is_bot": false,
          "headline": "chore(testing): use sqlite by default",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-12-06T19:23:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "afdabe66516ecd9ffc767b1a101d592a594d5825",
          "body": "* feat: separate mariadb driver\r\n* chore: add mariadb install dump",
          "is_bot": false,
          "headline": "feat: separate mariadb driver (#4132)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-12-02T09:17:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1755040252d7212536ff812cd2fe63978e77477b",
          "body": null,
          "is_bot": false,
          "headline": "Apply fixes from StyleCI",
          "author_name": "StyleCI Bot",
          "author_login": "StyleCIBot",
          "committed_at": "2024-11-29T12:54:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "944da2d402a7a25e9991d8a3c4b1ed5a895bcbdd",
          "body": "* chore(testing): run flarum/testing packages tests back again\r\n\r\nThese tests were not run on each framework build, I enabled them again.\r\nTwo of the tests were failing so I disabled them for now, it is more\r\nimportant to have some tests running than none at all.\r\n\r\n* chore(testing): remove flarum/t\n[…]\ng dedicated workflow\r\n\r\nIt is useless now that the tests are run in the framework repo.\r\nAlso this workflow was not working anymore.\r\n\r\n---------\r\n\r\nCo-authored-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "test(testing): run `flarum/testing` package tests (#3844)",
          "author_name": "Nicolas Peugnet",
          "author_login": "n-peugnet",
          "committed_at": "2024-11-29T12:54:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "06c627f02d552c1feb4973c94b8ba6f98a8e74d9",
          "body": "* test: php 8.4\r\n\r\n* fix: php 8.4 deprecations\r\n\r\n* fix: make argument required\r\n\r\n* chore: review changes",
          "is_bot": false,
          "headline": "test: php 8.4 (#4103)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-11-08T16:33:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "090079c4ef9fdbdbe5ae789641e280d4ed5462b0",
          "body": "* chore: phpunit 10\r\n\r\n* chore: config\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: phpunit 11 (php 8.2 minimum requirement)\r\n\r\n* feat: laravel 11\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* feat: carbon v3\r\n\r\n* fixes",
          "is_bot": false,
          "headline": "chore: update dependencies (#4012)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-08-06T15:50:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ac2d4b6b843a076dd98907520a2d8ec66815b5d",
          "body": "* feat: add support for `PgSQL`\r\n* chore: generate dump\r\n* feat: query exception errors db driver hint\r\n* feat: allow defining supported databases\r\n* chore: review comments\r\n* feat: setting for pgsql preferred search config",
          "is_bot": false,
          "headline": "feat: add support for PgSQL (#3985)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-06-22T07:03:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "77e2e63aa3371e1e0b34ef6d21778cbc96150bb3",
          "body": "* refactor: json:api refactor iteration 1\r\n* chore: delete dead code\r\n* fix: regressions\r\n* chore: move additions/changes to package\r\n* feat: AccessTokenResource\r\n* feat: allow dependency injection in resources\r\n* feat: `ApiResource` extender\r\n* feat: improve\r\n* feat: refactor tags extension\r\n* feat\n[…]\nt\r\n* feat: eager loading\r\n* test: adapt\r\n* test: phpstan\r\n* test: adapt\r\n* fix: typing\r\n* fix: approving content\r\n* tet: adapt frontend tests\r\n* chore: typings\r\n* chore: review\r\n* fix: breaking change",
          "is_bot": false,
          "headline": "refactor: JSON:API (#3971)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-06-21T08:36:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "93258af33f1c9232a907bb149409edc6d527960c",
          "body": "* feat: add support for sqlite\r\n\r\n* chore: add warning on install\r\n\r\n* fix: ignore constraints before transaction begins\r\n\r\n* chore: update workflow\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: generate sqlite dump and manually add foreign keys\r\n\r\n* chore: fix actions\r\n\r\n* chore: fix actions\r\n\r\n* chore\n[…]\nhore: fix actions\r\n\r\n* chore: fix actions\r\n\r\n* chore: fix actions\r\n\r\n* test: fix\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* fix: sqlite with db prefix\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* fix: statistics sqlite",
          "is_bot": false,
          "headline": "feat: add support for `SQLite` (#3984)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-06-21T06:25:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9ef773e68e13e5db7de907242c4744208844ad47",
          "body": "* feat: low maintenance mode (maintenance with admin access) (#3975)\r\n* feat: low maintenance mode (maintenance with admin access)\r\n* Apply fixes from StyleCI\r\n* chore: only required when basic\r\n* chore: more concise code\r\n* chore(review): enum\r\n* feat: enable through settings\r\n* Apply fixes from StyleCI\r\n* core: typing\r\n* feat: safe mode (#3978)\r\n* feat: safe mode\r\n* feat: add extension page warning\r\n* feat: `safe_mode_extensions`\r\n* Apply fixes from StyleCI",
          "is_bot": false,
          "headline": "feat: advanced maintenance modes (#3977)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-05-03T13:05:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "949b2d9b6ee015b219c88431c4ed858c4047666a",
          "body": null,
          "is_bot": false,
          "headline": "feat: eloquent factories (primarily for tests) (#3982)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2024-05-03T08:20:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "14823131be03781a356b50cf4858432f6953519f",
          "body": null,
          "is_bot": false,
          "headline": "Apply fixes from StyleCI",
          "author_name": "StyleCI Bot",
          "author_login": "StyleCIBot",
          "committed_at": "2024-01-09T15:06:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "450ea893c974aefd5f3e9c915d3ed22c0303b822",
          "body": null,
          "is_bot": false,
          "headline": "fix(testing): use cookie for testing authentication (#3924)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-11-10T21:35:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40167f9c7a0166c9a71cbd9df2a12616923dcff6",
          "body": "…ntract (#3862)\n\n* chore: merge the app with the container & implement the ApplicationContract\r\n\r\nIlluminate components always expect the app to be the container, but also expect the app to be implementing the laravel app contract. This means that very often between minor illuminate updates we get a\n[…]\n: service provider no longer has to change app type\r\n* chore: unimplement `terminat(e/ing)`\r\n* Apply fixes from StyleCI\r\n* chore: recover `container` prop\r\n* chore: return types\r\n* fix: phpstan errors",
          "is_bot": false,
          "headline": "chore: merge the app with the container & implement the ApplicationCo…",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-09-15T08:30:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "51828db2100eb056b47b5b904cedf0c50ea40944",
          "body": "* Do not catch exceptions when testing Console commands\r\n\r\nThis allows to easily test a case where a command should throw using `$this->expectException()`.\r\n\r\n* Rewrite ConsoleTest to use expectException\r\n\r\nNow that the ConsoleApplication is set to not catch exceptions.\r\n\r\n---------\r\n\r\nCo-authored-by: IanM <16573496+imorland@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Do not catch exceptions when testing Console commands (#3813)",
          "author_name": "Nicolas Peugnet",
          "author_login": "n-peugnet",
          "committed_at": "2023-06-21T07:14:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a93309ca44946351ff13b3f35185b5d8789dda96",
          "body": "…es (#3835)",
          "is_bot": false,
          "headline": "chore(phpstan): upgrade to be compatible with latest dependency updat…",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-06-15T16:49:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ff80f37855b9007f8a308b0099c3d9dca31e8a7",
          "body": "Allows running tests without constantly running `composer install` on each extension.",
          "is_bot": false,
          "headline": "chore: improve test suite (#3814)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-06-15T12:26:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe7f169672d8b774fff2b930036c359b16b14c5f",
          "body": "* wip: laraval and symfony upgrades\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* bump var dumper to 6.3\r\n\r\n* require guzzle 7.7\r\n\r\n* remove docbloc\r\n\r\n* lock symfony/translation-contracts to 2.5\r\n\r\n* fix: require mailgun package\r\n\r\n* remove docblock\r\n\r\n* fix: flysystem tests\r\n\r\n*\n[…]\n fixes from StyleCI\r\n\r\n---------\r\n\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>\r\nCo-authored-by: Daniël Klabbers <luceos@users.noreply.github.com>\r\nCo-authored-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "chore: Upgrade dependencies (#3830)",
          "author_name": "IanM",
          "author_login": "imorland",
          "committed_at": "2023-06-14T13:46:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bc34b358ed84147edf2ba4b546bfbf4be51ed1d1",
          "body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
          "is_bot": false,
          "headline": "fix(regression): caught errors",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-31T08:50:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2aaabd1d54e23eb92a45e0fa4fee6a996f300cef",
          "body": "* chore: set minimum php version to 8.1\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* chore: update codebase to php8.1\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: update workflow php version\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@g\n[…]\nail.com>\r\n\r\n* fix: one last error\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n---------\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
          "is_bot": false,
          "headline": "chore: update codebase to php8.1 (#3827)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-05-30T10:36:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd9251f9cf540c7df074bc6e7dfeb35de321efb4",
          "body": "This prevent tests from interacting between each other through the cache.",
          "is_bot": false,
          "headline": "fix(testing): always clear cache in integration test's tearDown (#3818)",
          "author_name": "Nicolas Peugnet",
          "author_login": "n-peugnet",
          "committed_at": "2023-05-02T18:24:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0c31cd504db6d395ba1da91178d36677ad761660",
          "body": null,
          "is_bot": false,
          "headline": "feat(testing): add a trait to flush the formatter cache in tests (#3811)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-04-30T08:48:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "35f96f607acb0798fe6828ce85d76b59ad0292fd",
          "body": "Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>\r\nCo-authored-by: David <hi@davwheat.dev>",
          "is_bot": false,
          "headline": "feat: access tokens user management UI (#3587)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2023-02-21T13:14:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44c92b807bd6e9926512fe9e2934f9f1bb69ba5e",
          "body": "* Make it possible to extend Flarum\\Testing\\integration\\Setup\\SetupScript and added public methods to add settings or extensions to in initial installation pipeline\r\n\r\n* Fix syntax error, unexpected 'static'\r\n\r\n* Remove `addExtensions` method and document `addSettings`",
          "is_bot": false,
          "headline": "feat(test): Make it possible to extend SetupScript (#3643)",
          "author_name": "Rafael Horvat",
          "author_login": "iPurpl3x",
          "committed_at": "2022-09-23T11:44:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ebd19f5443deada50b9528b937a221f1a2afd3b8",
          "body": null,
          "is_bot": false,
          "headline": "feat: customizable session driver (#3610)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-09-14T17:10:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64c6b2125c0da42cbb77deac5ea62913b97a0e0a",
          "body": null,
          "is_bot": false,
          "headline": "chore: v1.5.0 preparations",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2022-09-13T08:55:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9199962f6fcd3382a484c143fcbfef6c098f7f60",
          "body": "* test: password tokens are generated and deleted on password change\r\n* chore: delete all password tokens when the password is changed\r\n* test: email tokens are generated and deleted on email change\r\n* test: email tokens are deleted after password reset\r\n* chore: delete email tokens after password change\r\n* test: password tokens are deleted after email change\r\n* chore: delete password tokens after email change\r\n* chore: syntactic sugar\r\n* chore: unify event listening",
          "is_bot": false,
          "headline": "feat: clear password & email tokens when appropriate (#3567)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2022-07-30T12:02:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "37f36d0a7f87b8e7668e50a92f846b8ef1aee8c6",
          "body": "With all the commits below, we resolve all outstanding typing issues in the repo, and CI jobs run green.\r\n\r\n* fix: Convert DashboardPage and DashboardWidget to TypeScript\r\n\r\n* fix: fix type errors in package manager ext\r\n\r\n* fix: Convert Post component to TypeScript\r\n\r\n* fix: avatar typings should a\n[…]\nlarum-cli audit infra --monorepo --fix\r\n\r\n* feat: make `app.data` typings extensible\r\n\r\n* chore(core): format\r\n\r\n* chore: boost tags TypeScript coverage\r\n\r\n* fix(tags): further increase type coverage.",
          "is_bot": false,
          "headline": "fix: Assorted Typing Fixes (#3348)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-23T15:43:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "97df6620ce295b08502a43425b5060420922551d",
          "body": "…i/js (#3345)\n\n* chore(deps): bump glob-parent in /extensions/emoji/js\r\n\r\nBumps [glob-parent](https://github.com/gulpjs/glob-parent) from 3.1.0 to 5.1.2.\r\n- [Release notes](https://github.com/gulpjs/glob-parent/releases)\r\n- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)\r\n-\n[…]\nrt@github.com>\r\n\r\n* Apply fixes from StyleCI\r\n\r\n[ci skip] [skip ci]\r\n\r\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
          "is_bot": true,
          "headline": "chore(deps): bump glob-parent from 3.1.0 to 5.1.2 in /extensions/emoj…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2022-03-11T23:11:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "33cbae8106b6a5303c6c0284a705b28127f3ad30",
          "body": null,
          "is_bot": false,
          "headline": "chore: set up composer path repos",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-11T23:02:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a60493cff12a3f90392062f6edf53f04e76affd",
          "body": "- Remove .github conf folder from Flarum packages\n\n- Remove styleci config from all packages",
          "is_bot": false,
          "headline": "chore: remove centralizable repo config",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2022-03-11T23:01:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "617cf037e58e4c3ec1f1b84f5c2e9a1f6b008f30",
          "body": null,
          "is_bot": false,
          "headline": "allow empty db password \"\" again",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-06-21T07:32:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2b9890970975a5c6d8fd22eebe93ac691f98ed14",
          "body": null,
          "is_bot": false,
          "headline": "fix branch alias",
          "author_name": "Daniel Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-05-25T20:59:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fefd46886ff42c600ae035b71d0c97fa62ffd6b3",
          "body": null,
          "is_bot": false,
          "headline": "Update copyright year",
          "author_name": "David Wheatley",
          "author_login": "davwheat",
          "committed_at": "2021-05-14T23:58:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68bda3f994065797a08b93427b2219bec0f79dfc",
          "body": "Before boot, we consider them \"disabled\" so they get migrated.",
          "is_bot": false,
          "headline": "Extensions should be considered enabled after boot.",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-05-11T23:31:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0960a93d8be2eede83373773fcb2270423740ec3",
          "body": null,
          "is_bot": false,
          "headline": "Ensure that migrations run",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-05-11T21:15:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9ef0e5af606669865a0f9c8f8cec4c62af4f391b",
          "body": null,
          "is_bot": false,
          "headline": "get/set enabled extensions from test case, not DB",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-05-11T20:24:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7f4e2bbe8536403410870b5950d86e1ee3e36ed",
          "body": "The transaction is already started in the proper `BeginTransactionAndSetDatabase` extender.",
          "is_bot": false,
          "headline": "Remove second beginTransaction",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-05-03T05:27:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "06e04c6c24281621b127243ac6b828128cfa8cfc",
          "body": "In normal Flarum, extensions are only enabled during requests. Here, however, we enable some during boot. This resolves the FilesystemManager early, which resolves the Url Generator early. To fix this, we directly provide a filesystem disk for assets instead of getting it from the filesystem manager.",
          "is_bot": false,
          "headline": "Don't resolve routes early.",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-23T22:26:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d88991d1abfe28bc6bc7e31d2989f8f74547eb49",
          "body": null,
          "is_bot": false,
          "headline": "Ensure app is booted when getting database",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-23T19:20:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c7190e4565553a956cf5314190c55838848b265",
          "body": "This ensures a clean state for the extension currently being tested. The alternative requires the user to create and keep track of multiple test databases, or manually delete/re-recreate the database every time they switch between extensions being tested. Now, a simple `composer test:setup` will always reset the test environment to the original state.",
          "is_bot": false,
          "headline": "Drop all DB tables before installation during setup. (#9)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-20T18:47:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4d9caf8f8a2c4d353cca0a22b82b2ade07c2745",
          "body": "Similarly to `settings`, this allows setting/overriding config prior to application boot.",
          "is_bot": false,
          "headline": "TestCase Config method (#13)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-14T20:27:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c4b70b6bd2d76e27db884f9f0bed66c759b9d83",
          "body": null,
          "is_bot": false,
          "headline": "Remove UsesSettingsTrait (#12)",
          "author_name": "Sami Mazouz",
          "author_login": "SychO9",
          "committed_at": "2021-04-14T03:46:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "056d06663d7803762d6732ced9f33d1745cf8d44",
          "body": "This make a cleaner state more likely, and ensures that settings set via `$this->setting` are cleaned up after the test case runs.",
          "is_bot": false,
          "headline": "Start transactions before the app is fully booted. (#11)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-12T14:26:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eae3eca5183e8318c7b4642e00fd4debf0eade62",
          "body": null,
          "is_bot": false,
          "headline": "Add a few more automated tests",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-12T03:00:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "281d165edca3f6b81a29f60732defcce9aa4a8e4",
          "body": "Since we're making changes for the dev version of core, we should test against that too.\n\nFor now, this fixes issues with the `extensions` method of `Installation` being undefined.",
          "is_bot": false,
          "headline": "Test against dev version of core",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-12T02:47:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac376c810bf0fe6ff5e65e59eb730c1aa6d302cb",
          "body": null,
          "is_bot": false,
          "headline": "Don't enable extensions during installation (#7)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-08T22:39:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6dca45010855fa45ab571e440f49c1b834c4f98a",
          "body": null,
          "is_bot": false,
          "headline": "Add automated tests for `flarum/testing`",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-07T21:38:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "181fa93105700cc3fbc08f2950b947a1f57f1114",
          "body": "This allows adding settings before the app is booted. In the past we've used hacky workarounds like manually resetting a binding to override singletons to use custom setting values. It makes sense to support this through `TestCase`.",
          "is_bot": false,
          "headline": "Add `setting` method to integration TestCase",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-04-07T19:01:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "231101bfd1fe5400d82ab673f1283a747292dd4c",
          "body": "Add ext-json to composer requirements\r\nUpdate editorconfig to match core\r\nUpdate phpdoc to not reference missing import",
          "is_bot": false,
          "headline": "Requirement and formatting fixes (#5)",
          "author_name": "Clark Winkelmann",
          "author_login": "clarkwinkelmann",
          "committed_at": "2021-03-21T18:26:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d503e27159b6df6b4446e62ff4d1c0cef93d9aae",
          "body": "Replace bind with singleton, otherwise singleton behavior is lost",
          "is_bot": false,
          "headline": "Add missing import for ExtensionManager (#6)",
          "author_name": "Clark Winkelmann",
          "author_login": "clarkwinkelmann",
          "committed_at": "2021-03-21T18:25:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cc1d6940da87e1e317b908348f3309f4938463b2",
          "body": "It's not causing any issue because the correct variable name is always used to set and read the value, and PHP is fine setting new attributes on a class dynamically. It's just the explicit variables declared don't match with those actually used later.",
          "is_bot": false,
          "headline": "Fix variable names (#4)",
          "author_name": "Clark Winkelmann",
          "author_login": "clarkwinkelmann",
          "committed_at": "2021-03-20T22:46:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1756fcf740357f8a49066fc82adcdad19d549cac",
          "body": null,
          "is_bot": false,
          "headline": "Ignore generated tmp",
          "author_name": "SychO9",
          "author_login": "SychO9",
          "committed_at": "2021-03-11T18:07:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "859abdcdcf0468a511ae62544bd37add5515b5f9",
          "body": null,
          "is_bot": false,
          "headline": "Add required argument",
          "author_name": "SychO9",
          "author_login": "SychO9",
          "committed_at": "2021-03-11T18:07:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb60426e94d9a8a01233d331718dda51a5224927",
          "body": null,
          "is_bot": false,
          "headline": "Use mockery 1.4",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-03-06T23:58:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f2d4acde3908f6409be389f774f432933e3a1ea",
          "body": null,
          "is_bot": false,
          "headline": "Update PHPUnit to v9",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-03-06T23:38:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8b14bee7e6db7d5b3770f013462f10b062ed6b79",
          "body": null,
          "is_bot": false,
          "headline": "Update BuildsHttpRequests for new token system",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-03-06T23:38:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7f29633462e487114198cf5d7a3aee7696cde19",
          "body": null,
          "is_bot": false,
          "headline": "Configurable Tmp Dir Location (#2)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-02-10T13:59:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21cf1a3b061fbf081ded4356cd0dfa4fc32d2eff",
          "body": "Core's ExtensionManager only looks for extensions in the vendor directory, which makes sense for a Flarum instance, but is problematic if used in the context of a test suite for an extension. This PR:\r\n\r\n- Adds a class extending ExtensionManager to include the current package\r\n- Adds an extender that replaces ExtensionManager with this new class in container bindings\r\n\r\nEffectively, this package can now be used to test extensions.",
          "is_bot": false,
          "headline": "If current package is an extension, add it to the extension manager (#1)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-24T17:13:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "063c71a44ec0d242f8fce6e9cc2fad6c74911644",
          "body": null,
          "is_bot": false,
          "headline": "Fix vendor path",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T21:49:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27da25243f2ca60c0c6b9472a3e63c9db6177d70",
          "body": null,
          "is_bot": false,
          "headline": "Move setup script to importable class",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T21:22:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2401525a4e3085e206e807544636e2c7ae6cff52",
          "body": null,
          "is_bot": false,
          "headline": "Add composer.json",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:27:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "146f4c9d3543dda5ee2e41edb5cab8e4113048a8",
          "body": null,
          "is_bot": false,
          "headline": "Move test infrastructure to Testing namespace in src directory",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:27:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "551284de665ec9c6ed3f7378926caea96d61e14e",
          "body": "Some tests need to change settings, but since MemoryCacheSettingsRepository caches settings in-memory, those changes aren't reflected. The new `purgeSettingsCache` removes it from the container, eliminating that cache.\n\nFor UserTest, we also need to regenerate the display name driver, since that's set statically on boot, before we'll get a change to clear the settings cache.",
          "is_bot": false,
          "headline": "Tests: purge settings cache",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "290943b70b7e806eadbb48fabe952fd19f56d2e4",
          "body": null,
          "is_bot": false,
          "headline": "Add @inheritDoc to all setUp and tearDown methods",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79af839ee96ee607aa6b829c26e71c4d0dcb971f",
          "body": null,
          "is_bot": false,
          "headline": "Tests: Always start transaction before seeding",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c64712d7a45ddeac23d69a728a62a785698d8bd",
          "body": null,
          "is_bot": false,
          "headline": "Tests: Stop using Eloquent models for seeding data",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "003a48ea9aa844f88d1983573d2698fcedcab1b5",
          "body": null,
          "is_bot": false,
          "headline": "Tests: Rely on admin user, groups, permissions from test setup script",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "abd3ed841ee17be4161047a25490b08086f52011",
          "body": null,
          "is_bot": false,
          "headline": "Run integration tests in a transaction",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0cde58df60e4361d01b13ac964fc121597a6e593",
          "body": null,
          "is_bot": false,
          "headline": "Add vscode config to gitignore",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0a728626e493721bd670a2cd68e9916bf76f795",
          "body": null,
          "is_bot": false,
          "headline": "Improve developer experience by forcing LF line endings (#2321)",
          "author_name": "Wadim Kalmykov",
          "author_login": "w-4",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d0fecc6cfa1d6a6751bb33f050dd4f34126ac498",
          "body": null,
          "is_bot": false,
          "headline": "Use Config class for data from config.php",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "665b3a2822df18eb852d66ab3dda0b8a44b2743a",
          "body": "* Write source map without creating temp file\r\n\r\nLess I/O, and one less place where we access the global path helpers.\r\n\r\n* Drop useless app_path() helper\r\n\r\nThis was probably taken straight from Laravel. There is no equivalent\r\nconcept in Flarum, so this should be safe to remove.\r\n\r\n* Deprecate glo\n[…]\nm Application class\r\n\r\n* Avoid using public_path() in prerequisite check\r\n\r\na) The comparison was already outdated, as a different path was passed.\r\nb) We're trying to get rid of these global helpers.",
          "is_bot": false,
          "headline": "Clean up usages / deprecate path helpers (#2155)",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b4fb4b4eb3bb62647d851629d62e5f57709e61ed",
          "body": "We did pass multiple extenders to this method in the tests for the\n`Model` extender - now this actually has the desired effect.",
          "is_bot": false,
          "headline": "Tests: Actually accept multiple extenders",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9cecb797bee055c18796b57605da568329069dea",
          "body": "Not needed, and not working without a full Laravel installation.",
          "is_bot": false,
          "headline": "Test setup: Do not use env() helper",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7273de507fae8c0000de4fd1926a2c816e5991f6",
          "body": "- Stop trying to implement Laravel's Application contract, which\n  has no value for us.\n- Stop inheriting from the Container, injecting one works equally\n  well and does not clutter up the interfaces.\n- Inject the Paths collection instead of unwrapping it again, for\n  better encapsulation.\n\nThis brings us one step closer toward upgrading our Laravel\ncomponents (#2055), because we no longer need to adopt the changes\nto the Application contract.",
          "is_bot": false,
          "headline": "Split up Application and Container",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79230246bfc4ff97c26d0ff241f847f21928a901",
          "body": "* Made the console command system extender-friendly\n\n* Added console extender\n\n* Added ConsoleTestCase to integration tests\n\n* Added integration tests for console extender\n\n* Marked event-based console extension system as deprecated\n\n* Moved trimming command output of whitespace into superclass\n\n* Renamed 'add' to 'command'\n\n* Added special processing for laravel commands\n\n* Code style fixes\n\n* More style fixes\n\n* Fixed $this->container",
          "is_bot": false,
          "headline": "Add console extender (#2057)",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "094c45b192b1fc31a36a2f71c22e416ec356c6bc",
          "body": "[ci skip] [skip ci]",
          "is_bot": false,
          "headline": "Apply fixes from StyleCI",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5d297bbd644494a02b38978b0b1514e1e7690129",
          "body": "I feel this makes the parameters a bit more clear, does not rely on\ninheritance (you can only inherit from one class, but we might want more\nof these helpers in the future), and has less side effects (e.g. no\ncreation and, more importantly, deletion of users in the database).\n\nRefs #2052.",
          "is_bot": false,
          "headline": "Replace authenticatedRequest() by request() option",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9244753edc2914981ce9f5a08e2e0f4bf23d9a0b",
          "body": null,
          "is_bot": false,
          "headline": "Tests: Extract trait for building requests",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0653d109f44fc6488acd73da6f4083f74e9f13e3",
          "body": null,
          "is_bot": false,
          "headline": "Add Authenticated Test Case utility",
          "author_name": "Alexander Skvortsov",
          "author_login": "askvortsov1",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ed9263e211f62fc82540504dc38d1e516c09c62a",
          "body": null,
          "is_bot": false,
          "headline": "Integration tests: Allow registering extenders",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65dfe987613e502cbc8cbdc67fb7a761c932a940",
          "body": "This allows sending requests directly in an integration test, without\nhaving *explicitly* booted the app.",
          "is_bot": false,
          "headline": "Integration tests: Add lazy server helper",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acf74ebcc9cbe0acf87788669d0340f2b7060357",
          "body": "This will allow registering extenders in test scenarios. Previously,\nthis would not have had any effect as the app would have booted already.",
          "is_bot": false,
          "headline": "Integration tests: Create app lazily when needed",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf138360ac2895b6c8d138089a810ffa5b257d23",
          "body": "Also ensure backwards compatibility for extensions that use the Zend framework but don't explicitly require it.",
          "is_bot": false,
          "headline": "Change Zend namespace to Laminas (#1963)",
          "author_name": "Matt Kilgore",
          "author_login": "tankerkiller125",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f6e9974f289b2a38f58051efefd6a898c17bc6cc",
          "body": "[ci skip] [skip ci]",
          "is_bot": false,
          "headline": "Apply fixes from StyleCI",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c74bde8f9e7fd9a7b9227417ad197796d98b87be",
          "body": "- Use provided PhpUnit listener to enforce verification of expectations.\n- Include Mockery's trait to auto-close Mockery after each test.",
          "is_bot": false,
          "headline": "Automatically set up Mockery for unit tests",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "245b7ef62c5322ce428641e8c0ba5d5be0468e45",
          "body": "- Fix base url when is appended with a script filename\r\n- Add default base url http://flarum.local when CLI wizard used\r\n- Remove some code duplication\r\n- Add minor improvement to the UX when CLI wizard used\r\n- Add tests\r\n- Extract base url normalisation into its own value object",
          "is_bot": false,
          "headline": "Normalize Base URL during installation",
          "author_name": "Stefan Totev",
          "author_login": "relax4o",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d22fcd7a48ccd0e4337a0a6861cc4e064cb39947",
          "body": "…s from tempnam when storing files in tmp",
          "is_bot": false,
          "headline": "fixed tests on master, missing views directory and suppressing notice…",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8df5fd856ce96192e4ce0f6bcac6cc7ca199b42",
          "body": "[ci skip] [skip ci]",
          "is_bot": false,
          "headline": "Apply fixes from StyleCI (#1800)",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "81f7abd982cc08ec64091a9e689752ad3db7a187",
          "body": "…ver you re-run them once smtp is set.\n\nFixed, badly, the test to create users etc caused by the prepareDatabase flushing all settings by default.",
          "is_bot": false,
          "headline": "Using a different setting key now, so that it won't break tests whene…",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "692c18671fb336565edfaaab4c09aceffa1fe9d7",
          "body": "…to notice.\n\nFixed csrf test that assumed an access token allows application access, which is actually api token.\nImproved return type hinting in the StartSession middleware",
          "is_bot": false,
          "headline": "Fixed issue with tmp/storage/views not existing, this caused tmpname …",
          "author_name": "Daniël Klabbers",
          "author_login": "luceos",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0c6f7425faae9624b44d5a8369c04d630612e9f",
          "body": "Multiple tests now provide JSON request bodies, and others copy cookies\nfrom previous responses, so let's provide convenient helpers for these.",
          "is_bot": false,
          "headline": "Refactor tests to shorten HTTP requests",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68a8f24e23624c84a854bfcdc30a4562580aacd7",
          "body": "Now that this is possible, make the easy change...",
          "is_bot": false,
          "headline": "Integration tests: Configure vendor path",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ac90ab7ea0615431e69e6855528674917a4e3e3",
          "body": "This is useful to send HTTP requests (or their PSR-7 equivalents)\nthrough the entire application's middleware stack (instead of\ntalking to specific controllers, which should be considered\nimplementation detail).",
          "is_bot": false,
          "headline": "Integration tests: Memoize request handler as well",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21a79358ab80947eb7e602dcbc3c5f58c621e328",
          "body": null,
          "is_bot": false,
          "headline": "Integration tests: Fix test setup",
          "author_name": "Franz Liedke",
          "author_login": "franzliedke",
          "committed_at": "2021-01-13T06:21:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 22,
      "commits_last_year": 4,
      "latest_release_at": "2026-07-08T15:55:02Z",
      "latest_release_tag": "v2.0.0-rc.5",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 4,
      "days_since_latest_release": 19,
      "mean_days_between_releases": 48
    },
    "community": {
      "has_readme": false,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 62,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "flarum/testing",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "forum",
            "discussion"
          ],
          "ecosystem": "packagist",
          "matches_repo": true,
          "registry_url": "https://packagist.org/packages/flarum/testing",
          "is_deprecated": false,
          "latest_version": "v2.0.0-rc.5",
          "repository_url": "https://github.com/flarum/testing",
          "versions_count": 25,
          "total_downloads": 391233,
          "dependents_count": 411,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 21717,
          "first_published_at": null,
          "latest_published_at": "2026-04-18T09:09:56Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 101
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 0,
      "watchers": 4,
      "fork_history": {
        "days": [
          {
            "date": "2026-05-06",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "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": 11108,
      "source_files_sampled": 20,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "composer.json",
        "tests/composer.json"
      ],
      "advisories": {
        "error": "No resolved dependencies carried a version and a supported ecosystem",
        "scope": "repository_graph",
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 6,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "packagist"
      ],
      "dependencies": [
        {
          "name": "mockery/mockery",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^1.5"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "mockery/mockery",
            "direct": true,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "ext-json",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "flarum/core",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "flarum/testing",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "flarum/testing-tests",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "phpunit/phpunit",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 6,
        "direct_count": 1,
        "indirect_count": 5
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 12,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 1
      },
      "bus_factor": 2,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "askvortsov1",
          "commits": 31,
          "avatar_url": "https://avatars.githubusercontent.com/u/38059171?v=4"
        },
        {
          "type": "User",
          "login": "franzliedke",
          "commits": 23,
          "avatar_url": "https://avatars.githubusercontent.com/u/249125?v=4"
        },
        {
          "type": "User",
          "login": "SychO9",
          "commits": 22,
          "avatar_url": "https://avatars.githubusercontent.com/u/20267363?v=4"
        },
        {
          "type": "User",
          "login": "luceos",
          "commits": 7,
          "avatar_url": "https://avatars.githubusercontent.com/u/504687?v=4"
        },
        {
          "type": "User",
          "login": "imorland",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/16573496?v=4"
        },
        {
          "type": "User",
          "login": "clarkwinkelmann",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/5264300?v=4"
        },
        {
          "type": "User",
          "login": "n-peugnet",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/23519418?v=4"
        },
        {
          "type": "User",
          "login": "StyleCIBot",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/11048387?v=4"
        },
        {
          "type": "User",
          "login": "davwheat",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/7406822?v=4"
        },
        {
          "type": "User",
          "login": "johannsa",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/214734?v=4"
        }
      ],
      "contributors_sampled": 15,
      "top_contributor_share": 0.304
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": true,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "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": null,
            "reason": "no pull request found",
            "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/30 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 13 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "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": 0,
            "reason": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": null,
            "reason": "no dependencies found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file 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": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "8b4cf12e5a7dbedd7afbc5dc716c9cbc56248442",
        "ran_at": "2026-07-28T15:14:00Z",
        "aggregate_score": 4.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-28T13:17:57Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2021-04-20T18:47:07Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/flarum/testing",
    "host": "github.com",
    "name": "testing",
    "owner": "flarum"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 52,
      "inputs": {
        "security": 48,
        "vitality": 64,
        "community": 38,
        "governance": 75,
        "engineering": 27
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 64,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "at_risk",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 45,
            "inputs": {
              "commits_last_year": 4,
              "human_commit_share": 0.99,
              "days_since_last_push": 0,
              "active_weeks_last_year": 4
            },
            "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": "4/52 weeks with commits",
                "points": 2.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "4 commits in the last year",
                "points": 6.3,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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": 92,
            "inputs": {
              "releases_count": 22,
              "latest_release_tag": "v2.0.0-rc.5",
              "releases_from_tags": false,
              "days_since_latest_release": 19,
              "mean_days_between_releases": 48
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "22 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 22
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 19 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 19
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~48 days",
                "points": 19.8,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 48
                    }
                  }
                ],
                "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": 4,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 4 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "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": 38,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 3,
            "inputs": {
              "forks": 1,
              "stars": 0,
              "watchers": 4,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "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": "4 watchers",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "has_readme": false,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": 18,
                "status": "met",
                "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": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "good",
            "name": "Ecosystem adoption (downloads)",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "packages": [
                "flarum/testing"
              ],
              "dependents": 411,
              "ecosystems": "packagist",
              "total_downloads": 391233,
              "monthly_downloads": 21717
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "21,717 downloads/month across packagist",
                "points": 57.8,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 21717,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "411 packages depend on it",
                "points": 17.4,
                "status": "partial",
                "details": [
                  {
                    "code": "registry_dependents",
                    "params": {
                      "count": 411
                    }
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "good",
        "name": "Sustainability & Governance",
        "value": 75,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "moderate",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 64,
            "inputs": {
              "bus_factor": 2,
              "contributors_sampled": 15,
              "top_contributor_share": 0.304
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "2 contributor(s) cover half of all commits",
                "points": 25.2,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 30% of commits",
                "points": 15.7,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 30
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "15 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 15
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 13 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 66,
            "inputs": {
              "merged_prs": 12,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 1
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "12/13 decided PRs merged",
                "points": 35.3,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 12,
                      "decided": 13
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "followers": 798,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "flarum",
              "public_repos": 53,
              "account_age_days": 4688
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "798 followers of flarum",
                "points": 20.9,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 798,
                      "login": "flarum"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "53 public repos, account ~12 yr old",
                "points": 24.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 53
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 12
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "flarum/testing"
              ],
              "ecosystems": "packagist",
              "any_deprecated": false,
              "min_days_since_publish": 101
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on packagist",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 101 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 101
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "25 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 25
                    }
                  }
                ],
                "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": "critical",
        "name": "Engineering Quality",
        "value": 27,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "at_risk",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 38,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 6.4,
                "status": "met",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "critical",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": false,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": null,
                "points": 0,
                "status": "missed",
                "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 48,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "dangerous_workflow",
                    "packaging",
                    "pinned_dependencies",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 48,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 12,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 6,
              "scorecard_aggregate": 4.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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 13 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "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": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "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": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "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": 21
            },
            "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": "at_risk",
        "name": "AI Readiness",
        "value": 39,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 34,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.636,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "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": "63 of 99 human commits state their intent (structured subject or explanatory body)",
                "points": 33.9,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 63,
                      "sampled": 99
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_pinned_dependencies"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 36,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.01,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.01
            },
            "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": 0,
                "status": "missed",
                "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "1 of the last 100 commits agent-authored or agent-credited",
                "points": 2,
                "status": "partial",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 1,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "1 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 1,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "primary_language": "PHP",
              "largest_source_bytes": 11108,
              "source_files_sampled": 20,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "PHP without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "PHP"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/20 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 20,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "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": [
    "No resolved dependencies carried a version and a supported ecosystem"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T15:14:13.222055Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/f/flarum/testing.svg",
  "full_name": "flarum/testing",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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