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

One-Learning-Community / laravel-model-explorer

Model Explorer for Laravel — a zero-config browser UI and MCP server for exploring your Eloquent models, relationships, scopes, and data.

PHP · VueMIT★ 7 зірок⑂ 0 форківз бер. 2026 р.Переглянути на GitHub ↗

One-Learning-Community/laravel-model-explorer має індекс здоров’я 62 зі 100, що відповідає смузі «Помірний». Найвищий показник — Vitality (82/100), найнижчий — Community & Adoption (37/100). Останнє оновлення було 5 днів тому. Більшість нещодавньої роботи виконує один учасник.

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

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

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

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

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

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

Власність

One Learning CommunityОрганізація
0 підписників27 публічних репозиторіївз бер. 2020 р.

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

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

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікаціяТеги
Packagistonelearningcommunity/laravel-model-explorerv0.5.220 8991015 днів томуlaravelmodelseloquentdeveloper-toolsaimcpmodel-context-protocol

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

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

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

82Добрий · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 5 дн. тому
5.5/36Ритм комітів — 8/52 тижнів із комітами
18/18Обсяг комітів — 157 комітів за останній рік
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Використані вхідні дані
commits_last_year157
human_commit_share0,89
days_since_last_push5
active_weeks_last_year8
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 8 релізів
36/36Свіжість релізів — останній реліз 16 дн. тому
27/27Ритм релізів — реліз кожні ~14,7 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count8
latest_release_tagv0.5.0
releases_from_tagsні
days_since_latest_release16
mean_days_between_releases14,7
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

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

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

37У зоні ризику · 18% загального індексу
Як обчислюється оцінка
12.6/60Зірки — 7 зірок
0/25Форки — 0 форків
0/15Спостерігачі — 0 спостерігачів
Використані вхідні дані
forks0
stars7
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
0/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
has_contributingні
has_issue_templateні
has_code_of_conductні
has_pull_request_templateні
Як обчислюється оцінка
57.6/80Щомісячні завантаження — 20 899 завантажень/місяць у packagist
0/20Залежні пакети в реєстрі — залежних пакетів: 0
Використані вхідні дані
packagesonelearningcommunity/laravel-model-explorer
dependents0
ecosystemspackagist
total_downloads28 281
monthly_downloads20 899

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

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

55Помірний · 24% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
0/22.5Розподіл комітів — головний контриб’ютор — автор 100% комітів
1.4/13.5Широта контриб’юторів — 1 контриб’юторів
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Використані вхідні дані
bus_factor1
contributors_sampled1
top_contributor_share1
Як обчислюється оцінка
0/46.8Вирішення issue — немає issue або даних
38.2/38.3Прийняття PR — злито 9/9 вирішених PR
0/15OpenSSF Scorecard: Code-Review — Found 0/28 approved changesets -- score normalized to 0
Використані вхідні дані
merged_prs9
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Виключено з оцінювання (немає даних або не застосовно): Вирішення issue. Залишкові ваги перенормовано.
Як обчислюється оцінка
30/30Підтримка власника — у власності організації
0/20Верифікований домен
0/25Охоплення власника — 0 підписників у One-Learning-Community
22.5/25Послужний список — 27 публічних репозиторіїв, вік облікового запису ~6 р.
Використані вхідні дані
followers0
owner_typeOrganization
is_verified
owner_loginOne-Learning-Community
public_repos27
account_age_days2 316

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

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

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

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

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

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

90Відмінний
Як обчислюється оцінка
30/30README
25/25Каталог документації
15/15Сайт документації / домашня сторінка — https://one-learning-community.github.io/laravel-model-explorer/
10/10Опис репозиторію
10/10Теми — 10 тем
0/10Wiki
Використані вхідні дані
topicseloquent, eloquent-orm-models, laravel, ai, developer-tools, laravel-package, mcp, model-context-protocol, php, vue
has_wikiні
homepagehttps://one-learning-community.github.io/laravel-model-explorer/
has_readmeтак
has_docs_dirтак
has_descriptionтак

Безпека

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

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

Стан безпеки

51Помірний
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 1 out of 1 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/28 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
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
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — немає даних
0/5Pinned-Dependencies — немає даних
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — немає даних
0/7.5Token-Permissions — немає даних
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated13
scorecard_versionv5.5.0
checks_inconclusive5
scorecard_aggregate5,1
Виключено з оцінювання (немає даних або не застосовно): dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions. Залишкові ваги перенормовано.

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

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

46У зоні ризику · 0% загального індексу
Як обчислюється оцінка
0/45Інструкції для агентів — немає CLAUDE.md / AGENTS.md / правил редактора
0/15Машиночитана документація (llms.txt)
40/40Читабельна історія комітів — намір зазначено у 79 з 89 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,888
agent_instruction_files
agent_instruction_max_bytes
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
0/11Конфігурація лінтера / форматера
0/11Статична перевірка типів
10/10Відтворюване середовище — lockfile
10/10Підтверджена практика роботи з агентами — 67 з останніх 100 комітів створено агентом або з його зазначенням
8/8Автоматизоване супроводження — 9 з останніх 100 комітів — автоматичні оновлення залежностей
0/10OpenSSF Scorecard: Pinned-Dependencies — немає даних
Використані вхідні дані
has_nixні
has_testsтак
lockfilespackage-lock.json
has_dockerfileні
typed_languageні
bootstrap_files
has_devcontainerні
has_linter_configні
typecheck_configs
agent_commit_share0,67
toolchain_manifests
dependency_bot_commit_share0,09
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Pinned-Dependencies. Залишкові ваги перенормовано.
Як обчислюється оцінка
0/45Типізований код — PHP без конфігурації перевірки типів
54.5/55Керовані розміри файлів — 1/101 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languagePHP
largest_source_bytes168 434
source_files_sampled101
oversized_source_files1
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
20/20Сервер MCP
0/40Придатні до запуску приклади
Використані вхідні дані
example_dirs
has_mcp_signalтак
api_schema_files

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

7зірок GitHub
1контриб'юторів
157комітів за останні 12 місяців
5днів від останнього пушу
8релізів
1бас-фактор
0відкритих issue
npm, Packagistпакетних екосистем

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

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Докладніше

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

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests1 out of 1 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/28 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
н/дDangerous-Workflowno workflows found
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
н/дPackagingpackaging workflow not detected
н/дPinned-Dependenciesno dependencies found
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
н/дSigned-Releasesno releases found
н/дToken-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
Прямі залежності 8
РеєстрПакетОбмеження версіїМаніфест
Packagistilluminate/contracts^11.0||^12.0||^13.0composer.json
Packagistlaravel/mcp^0.9.0composer.json
Packagistspatie/laravel-model-info^2.0composer.json
Packagistspatie/laravel-package-tools^1.16composer.json
npmlucide-vue-next^0.577.0package.json
npmprismjs^1.30.0package.json
npmvue^3.5package.json
npmvue-router^4.6.4package.json
Усі залежності не зібрано

Не вдалося зібрати розв'язаний набір залежностей для цього звіту: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [
        "eloquent",
        "eloquent-orm-models",
        "laravel",
        "ai",
        "developer-tools",
        "laravel-package",
        "mcp",
        "model-context-protocol",
        "php",
        "vue"
      ],
      "is_fork": false,
      "size_kb": 2078,
      "has_wiki": false,
      "homepage": "https://one-learning-community.github.io/laravel-model-explorer/",
      "languages": {
        "CSS": 69,
        "PHP": 263449,
        "Vue": 81658,
        "Blade": 4181,
        "JavaScript": 6174
      },
      "pushed_at": "2026-07-17T00:45:32Z",
      "created_at": "2026-03-20T22:50:41Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-17T00:45:29Z",
      "description": "Model Explorer for Laravel — a zero-config browser UI and MCP server for exploring your Eloquent models, relationships, scopes, and data.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "PHP",
      "significant_languages": [
        "PHP",
        "Vue"
      ]
    },
    "owner": {
      "blog": "https://www.onelearningcommunity.com",
      "name": "One Learning Community",
      "type": "Organization",
      "login": "One-Learning-Community",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/62369849?v=4",
      "created_at": "2020-03-19T05:01:08Z",
      "is_verified": null,
      "public_repos": 27,
      "account_age_days": 2316
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-05T18:05:29Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-06-30T20:16:38Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-06-30T19:55:06Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-06-30T12:58:22Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-06-30T05:21:26Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-06-30T00:39:39Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-03-25T06:06:52Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-03-24T19:47:43Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "c81565e6424a37474d09050ccd4c119758580601",
          "body": "…r/laravel/mcp-tw-0.9.0\n\nchore(deps): update laravel/mcp requirement from ^0.8.2 to ^0.9.0",
          "is_bot": true,
          "headline": "Merge pull request #10 from One-Learning-Community/dependabot/compose…",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-17T00:45:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf75cd8e777824236ce5257312ca7c09a7ad7fa5",
          "body": "Updates the requirements on [laravel/mcp](https://github.com/laravel/mcp) to permit the latest version.\n- [Release notes](https://github.com/laravel/mcp/releases)\n- [Changelog](https://github.com/laravel/mcp/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/laravel/mcp/compare/v0.8.2...v0.9.0)\n\n---\nupdated-dependencies:\n- dependency-name: laravel/mcp\n  dependency-version: 0.9.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): update laravel/mcp requirement from ^0.8.2 to ^0.9.0",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-17T00:44:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fde110aa17041342485bcbee68b3e47972f7556",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.5.2",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-07T02:59:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "24bd4d6675d08e3c2f0818b34743a179e426ba31",
          "body": "The negative \"not member\" was over-repeated. Positive framing in the\nalways-loaded surfaces (description names its params; schema hint just names\nthe member) reads as more authoritative and avoids keeping the wrong key\nsalient. The corrective \"it's name, not member\" now fires only where the\nmistake already happened — the unknown-param guard and name.required.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: keep the \"name not member\" correction on the error path only",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-07T02:57:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "10cb48084711139fb95d8de9ac481b00b8df0a5f",
          "body": "The tool's member argument is `name`, but the \"one defined member\" prose led\nagents to guess `member` and hit an unhelpful \"The name field is required\".\n\n- Reject unknown params with an error that names the offending key and lists\n  the accepted set (model/name/kind), pointing the member at `name`.\n\n[…]\nd\n  recommend model-source over grepping getXAttribute/scopeX/relation bodies\n  (it resolves through the real trait/parent chain).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: make model-source self-correct the \"member\" vs \"name\" param mistake",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-07T02:52:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "13784b60bd62fa397bbc843d59c0131cd849f70a",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.5.1",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T18:31:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b952db2879a43093d8809775e0182671f3531219",
          "body": "Every scope/relation/accessor/member pointer from inspect-model,\nmodel-source, and model-neighbors now carries the snippet's start AND\nend line (e.g. app/Models/Post.php:42-58) instead of just the start,\nso an agent can do a targeted read of exactly the method it wants to\nedit. Single-line members c\n[…]\nemits end_line, which propagates through the shared\nDTOs to CompactPresenter::pointer() — the one formatter all three tools\nshare.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: report full line range (path:start-end) in MCP defined_in pointers",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T18:26:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "71ae0a47e87af4f232d426804f246cb8ce56e82a",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.5.0",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T18:05:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fce1e6f7717996acc3b151aedc44303672e228aa",
          "body": "Factory detection used Factory::resolveFactoryName() + class_exists, which only\nsees the name resolver — so a model pointing at a non-conventionally-named\nfactory (a $factory property, #[UseFactory], custom newFactory(), or a package\ntrait like HasPackageFactory) resolved to the wrong guessed name a\n[…]\nhe\ndegrade-to-null case; User covers no-HasFactory. Removes the newFactory()-override\nlimitation previously documented in ADR-014.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: resolve factory through Model::factory(), not the convention guess",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T17:57:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "327e2435f386e49efbcb7fa18c5e991978f47098",
          "body": "Quick \"where do I read the factory to write a test?\" pointer — not a parse of\nthe factory's definition/states. inspect-model's overview gains a present-only\n`factory` object (class + defined_in path:line); the Model Detail page shows a\n`factory:` badge.\n\nDetection uses Laravel's own Factory::resolve\n[…]\nstFactory; tests cover present, absent (User),\nthe class_exists gate, and the reflection path across inspector/presenter/API/tool.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: surface a model's factory when one exists (MCP + UI)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T17:40:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "102e89f93f41a0e5fc197e04ce04b82020550a8e",
          "body": "The suite only exercised the string-backed PostStatus enum. Add:\n- Priority (int-backed) cast on posts.priority, asserting cases serialize\n  with integer values (1, not \"1\") — the branch that was unverified in-suite.\n- An env-var wiring test proving MODEL_EXPLORER_MCP_ENUM_CASES feeds the\n  mcp.enum\n[…]\nved config value were tested, not the env→config path).\n\nNo production code change — closes verification gaps surfaced in testing.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: cover int-backed enum expansion + env-var enum knob",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T17:05:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c2037223fc20284cb813acaa5d68d1de3211b720",
          "body": "`indexed` flagged every column of a composite index as if independently\nfilterable — a 4-column composite marked all four, misleading an agent about\nlone-filter cost. Annotate the role instead:\n  - '' single-column index          → `indexed`\n  - leading column of a composite    → `indexed(composite-\n[…]\ns from array<string,bool> to array<string,string> (role\nlabel). Fixture: IndexedRecord with a single index + a 3-column composite.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: composite index over-reported every member as plainly indexed",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T17:05:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eb824f1397535ea1d5acf65ca3898afa412d9f81",
          "body": "extractRelationMeta() gated through-relation detail on `instanceof\nHasManyThrough`. Laravel 11+ moved HasOneThrough and HasManyThrough under a\nshared HasOneOrManyThrough base — HasOneThrough no longer extends\nHasManyThrough — so hasOneThrough fell through to the bare return with no\nthrough / through\n[…]\nCountry::firstPost() hasOneThrough (the suite previously\nexercised only hasManyThrough, which is how the L11 change slipped past).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: hasOneThrough relation detail came back blank (L11+ hierarchy)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T17:04:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "879e4ca0c265ba879cc958b5bcc711e46c80a58e",
          "body": null,
          "is_bot": false,
          "headline": "Fix styling",
          "author_name": "serpentblade",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T15:37:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e73781ce0d4d0067b2e5fb86f0739931153fb92",
          "body": "Enum expansion is the only column enrichment that grows with model size, so\ngive it a lever while leaving the near-free index/relation detail always-on.\n\n- config: mcp.enum_case_limit (MODEL_EXPLORER_MCP_ENUM_CASES, default 12).\n  0 omits enum cases entirely; N caps at N.\n- inspect-model gains an en\n[…]\nse list;\n  the cap is an MCP-token concern only.\n\nDocs: mcp.md (config + param + Enum-case verbosity section), ADR-014, CHANGELOG.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: make MCP enum-case expansion tunable (config + per-call param)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T15:17:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "29be2e20758dca6063831fcbfe5b4395a7db3c24",
          "body": "- ADR-014 records the shared-DTO enrichment decision (enum cases, indexed\n  flag, pivot/morph/through relation detail) and the side-map architecture.\n- mcp.md: column strings now show `indexed` and inline enum cases; relation\n  objects document the pivot/morph_type/through keys with an example.\n- mo\n[…]\n detail sub-line.\n- CLAUDE.md ADR index: add ADR-013 (was missing) and ADR-014.\n- CHANGELOG: three Added entries under Unreleased.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: ADR-014 + document enum/index/relation enrichment",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T06:35:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "36da4cd2a731f9f707a18104f56642fd35924935",
          "body": "Relations now carry the structural detail an agent needs to actually write a\nquery or migration against them, beyond name/type/related/via:\n\n- Many-to-many (BelongsToMany/MorphToMany): pivot table, both pivot keys, and\n  the withPivot() extra columns.\n- Polymorphic (MorphTo/MorphOne/MorphMany/MorphT\n[…]\nkbench: Tag/Video (m2m pivot), Comment (morphTo), Video (morphMany),\n  Country (hasManyThrough Post via User), + users.country_id.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: richer relation detail — pivot, morph type, through (MCP + UI)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T06:32:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0e470489d27c7e6b5309c2313cd0ab62a9b69cb8",
          "body": "Surface which columns participate in a non-unique database index so an agent\n(or developer) can tell at a glance whether a filter is cheap. PK and unique\ncolumns are skipped — already flagged and implicitly indexed.\n\n- ModelData gains an indexedColumns side-map, produced in ModelInspector via\n  the \n[…]\nol per attribute; ColumnsTable.vue renders an\n  \"indexed\" badge beside \"unique\".\n- Workbench: a plain index on posts.published_at.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: flag non-unique indexed columns (MCP + UI)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T06:18:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "19111ce416c2c510c9f41cceff2775ca856e2b54",
          "body": "When a column casts to a PHP enum, surface the enum's cases so an agent (or\na developer in the Model Detail UI) sees the valid values without opening the\nenum file. Backed enums render Name=value; pure enums render names only.\n\n- ModelData gains an enumCasts side-map (column → cases), produced in\n  \n[…]\nlumnsTable.vue renders the\n  cases as chips under the cast.\n- Workbench: PostStatus backed enum cast on a new posts.status column.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: expand enum casts into their cases (MCP + UI)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T06:13:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9d41040ab14f2cfc781940227c9bd64c71de5368",
          "body": "…relation detail)\n\nDesign for three shared-surface enrichments benefiting both the MCP tools\nand the browser Model Detail page: enum cast expansion, a non-unique index\nflag, and richer pivot/morph/through relation detail. Side-map architecture\non ModelData (mirrors accessorSnippets); RelationData extended directly.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: spec for column & relation enrichment (enum cases, index flag, …",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T06:03:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d4b91e17c60b72c06c068029dc063dc8fa752a67",
          "body": "Enable outline [2,3] so each tool section appears in the \"On this page\"\nnav. Remove the relationship-graph removal callout and ADR-012/013\ncitations — dead weight for a tool that was cut and internal refs the\nreader can't see.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: tighten MCP page, drop removed-tool apologia, add h3 outline",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-05T05:07:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "21f4be08e2506c09843e2aaf3f00e79c4195e47d",
          "body": "Getting Started only covered the browser UI. Add a short MCP section\n(client config snippet + trust-boundary note) between Accessing the UI\nand Authorization, since the MCP server is independent of the HTTP\ngate, and link to the full guide for the tool reference.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add MCP setup to Getting Started, link to full reference",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-03T02:09:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "001ca470ce12591e6c1045aec09acdc9576db3e3",
          "body": "MCP introspection is the more differentiating feature over the browser\nUI, so lead with it: README intro/feature list and the docs-site hero\nnow mention agents first, and the README's MCP section moved up next\nto Usage instead of being buried after Configuration/Caching.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: promote MCP to lead feature in README and docs home page",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-02T23:42:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d8c8231061c0249300ebabd0ebb7b986231edc34",
          "body": "The \"Using Laravel Boost?\" tip claimed boost:install needs no manual\nclient config. That's wrong — Boost only ships text guidelines telling\nan agent the server exists; it has no hook to register a third-party\nMCP server into the client config. ADR-011 already documented this\ncorrectly, but the docs site had drifted from it.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: fix misleading Boost auto-registration claim on MCP page",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-07-02T23:37:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "15b8f7c10adf0762f48750eaa735b8103e85b161",
          "body": "…l-explorer",
          "is_bot": false,
          "headline": "Merge branch 'main' of github.com:One-Learning-Community/laravel-mode…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T20:15:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0057a04f946296af0511e6632fe7e084f7da7ee1",
          "body": "Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.4.1",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T20:14:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b923c99cb07d0c07d76910f85f888984c13106ae",
          "body": "The Boost guidelines, server Instructions, find-model's description, and\nmodel-neighbors' description now explicitly state these tools answer what is\ndefined on a model and where it comes from — not where it's referenced or\ncalled. Points agents at a text search (grep) for call sites, usage beyond\nE\n[…]\nn for a call-site search either.\n\nAlso fixes the server Instructions text, which had dropped \"members\" from\nits list of inspect-model sections.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: clarify the MCP tool surface answers structure, not usage",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T20:14:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ef18698ab18e89755896048f2c2e14e92b360eb9",
          "body": null,
          "is_bot": false,
          "headline": "Fix styling",
          "author_name": "serpentblade",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T19:54:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a9d25ab7ca99526b3aeb1f3de53e640519b69be",
          "body": "Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.4.0",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T19:54:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "be9264de063fbb07346cc76f0929b92d901226ae",
          "body": "Records the decision to ship a new model-neighbors tool (rather than\nreviving relationship-graph under its old name or extending find-model),\nthe incoming-by-default direction, depth reserved-but-validated-to-1, and\nlimit as a per-call parameter rather than a config knob. Adds a forward\nreference fr\n[…]\ntion. Updates the Boost\nguidelines, README, MCP guide (new tool table entry + section + vendor-hatch\nnote), and CHANGELOG to describe the tool.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add ADR-013 and document model-neighbors across the MCP docs",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T19:34:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "37e1ebd529a48c38735420f2fb84c50b1aa59619",
          "body": "The scoped graph return ADR-012 anticipated when it retired the whole-graph\nrelationship-graph tool: root model + bounded depth + limit + truncated flag,\ninstead of dumping the entire universe. Addresses the \"blast radius\" gap —\n\"what breaks if I touch this model\" — by answering the inverse directio\n[…]\nined_in pointers via the snippet GraphBuilder\n  now threads through.\n\nRegistered as the fifth MCP tool. See ADR-013 (added in the next commit).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add model-neighbors, a scoped depth-1 relation-neighborhood query",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T19:28:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2ebd7f7fda3cd0076f78821631ded5a7b94daa87",
          "body": "Each relation entry in GraphBuilder::build()'s output now includes the\nRelationData snippet (file + start_line), in addition to name/type/related.\nGraphBuilder already inspects every model to compute the graph, so this\ncosts nothing extra — it just stops discarding data a consumer might want.\n\nAddit\n[…]\nrk\nfor the model-neighbors MCP tool, which needs trait-correct defined_in\npointers on incoming-relation edges without a second inspection pass.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: carry relation source snippets through GraphBuilder",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T19:24:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "091b0c3e4aa720b2d2f0c4306870848477755f7f",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'feat/mcp-adr-012-open-questions'",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T18:57:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a7ce5998f12786cacd6b3379d323c224e1b7ff2",
          "body": "Updates ADR-012's status and open-questions section to record how each\nquestion was resolved (with a note on the members-filter follow-on gap that\nsurfaced while shipping model-source's unrestricted kind). Updates the Boost\nguidelines, README, and MCP guide to describe model-source's optional kind,\nthe members:<kind>/members:file= include filters, and find-model's\ndefinesMember filter.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: resolve ADR-012's open questions and document the new MCP filters",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T18:56:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e34afe40f879e21f338fc3baa06b88a87afe872d",
          "body": "The structural analogue of hasColumn, but over the first-party members\nsurface (MemberExtractor) instead of database columns. \"Which models define\ntoSearchableArray?\" becomes a first-class query instead of a source grep that\nmisses trait composition — matches trait-composed members the same way\nhasC\n[…]\nesTo already do, by inspecting the resolved ModelData\nrather than the raw class declaration.\n\nCloses the third and final ADR-012 open question.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add a definesMember filter to find-model",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T18:52:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e26cbeadab205730f78bb795c35e13036be5933e",
          "body": "A noisy class can return hundreds of members (377 on the app that prompted\nADR-012), which inverts the token-cost story the members section was meant\nto fix. `include` now accepts \"members:<kind1>,<kind2>\" (e.g.\n\"members:relation,business\") to narrow by kind, or \"members:file=<substring>\"\nto narrow \n[…]\nhe unfiltered total, so the filter narrows what's returned without hiding\nhow big the full surface is.\n\nCloses the first ADR-012 open question.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: filter inspect-model's members section by kind or declaring file",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T18:49:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b5efdba92ab6605bfb711c3f318bcda58644cf58",
          "body": "…cessor\n\n`kind` is now optional and unrestricted — omit it to resolve by name alone\nacross scopes, relations, accessors, and the wider members list (business\nmethods, lifecycle hooks, properties, constants, ...). This completes the\n\"enumerate with members, then fetch the one body\" workflow for any m\n[…]\nrDeclarationLine() for the property/constant case,\nwhich has no reflectable body, just a source line.\n\nCloses the second ADR-012 open question.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: let model-source resolve any member, not just scope/relation/ac…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T18:40:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9f4b2cabff0f04b9ace9608630da9ba1d38adb04",
          "body": null,
          "is_bot": false,
          "headline": "Fix styling",
          "author_name": "serpentblade",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T12:58:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e3d9dfda791deded1a30b4f57d9c755989a09a2b",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.3.2",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T12:58:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "adbfbf91205672c4eb789407472198a7603abe06",
          "body": "Reflect the refined MCP surface across the user-facing docs: drop the\nremoved relationship-graph tool (now four tools, with a pointer to the\nbrowser graph), document the new inspect-model `members` section, and\ndocument MODEL_EXPLORER_MCP_ALLOW_UNDISCOVERED for inspecting vendor /\nundiscovered models by FQCN. Adds an Unreleased changelog entry.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: update README, MCP guide, and changelog for ADR-012",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T06:30:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5b184ee6afa73d5d6e7875021d9687ef050f180c",
          "body": "Closes the \"skeleton, not behavior\" gap: inspect-model can now return\nevery first-party-defined member of a model — methods, properties, and\nconstants — each with a heuristic `kind` (relation/scope/accessor/\nlifecycle/business/config/constant/…) and a trait-correct `defined_in`\npointer. Names, signa\n[…]\nsult. Shipped as an opt-in `members` include (off by default,\nsurfaced in counts.members), per the resolved ADR-012 open question.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add a members section to inspect-model (ADR-012 C)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T06:22:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ae5721b6573a84d8397583e4c32a3c1a68d8db43",
          "body": "ModelResolver now accepts a fully-qualified Eloquent model that lives\noutside model_paths when mcp.allow_undiscovered is enabled (default off),\nso inspect-model / model-source can introspect a vendor package's model\ninstead of refusing valid input. Short names stay bounded to the\ndiscovered set, so \n[…]\nre unaffected. With the flag\noff, a valid vendor FQCN now gets an actionable hint instead of a flat\n\"No discovered model\" refusal.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: inspect undiscovered vendor models behind an opt-in (ADR-012 B)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T06:08:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "27ade33e61cd829c25e1749dc2917adbb43c1787",
          "body": "The tool could only return the entire graph, which overflows the MCP\nclient's per-result budget at real scale (audited app: 224 nodes / 762\nedges ~ 88 KB) and no audited agent task needed it that find-model /\ninspect-model did not serve better. Remove it from the agent surface\nalong with its now-orp\n[…]\nllet. GraphBuilder and the HTTP/SPA graph endpoint stay for\nthe human view; a scoped (root + bounded depth) tool may return later.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: retire the relationship-graph MCP tool (ADR-012 A)",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T06:08:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1491214e54c2db0433eb13195d610fec81e6c52b",
          "body": "ADR-012 captures the three audit gaps and the directions for each:\nretire the whole-graph MCP tool (A), add a vendor-model escape hatch (B),\nand add list-members (C). A & B are shipped in the following commits; C is\nin progress. ADR-011 flipped to \"implemented\" since src/Mcp shipped.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: record ADR-012 (MCP surface refinement); mark ADR-011 implemented",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T06:08:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6e9414171bbe9a91a70234fa47e825726f01f88a",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: promote changelog Unreleased to v0.3.1",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T05:20:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f50574095b6a9099bb355ee98018259e5bd29750",
          "body": "…ut a restart\n\nThe mcp:start server is a persistent PHP process, and PHP cannot redefine a\nclass once loaded. So after a model's structure was edited, the server kept\nreporting the reflection of the version it first loaded until reconnected —\nthe staleness behind the original audit.\n\ninspect-model/f\n[…]\ntests for the command's serialized\npayload, subprocess payload parsing/failure, and the in-process-vs-subprocess\nrouting decision.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: serve accurate inspections from the long-lived MCP server witho…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T05:15:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bb5547a894fdc08d10b98ab853135881a46660f5",
          "body": "Cache keys were keyed only by class name (MCP inspect/find/list/graph) or a\nbare name (web list/graph), so enabling MODEL_EXPLORER_MCP_CACHE or\nMODEL_EXPLORER_CACHE served stale metadata after a model file was edited,\nuntil a manual model-explorer:clear. A long-lived mcp:start process made this\nespe\n[…]\nourceFingerprintTest and an InspectModelTool cache test that\nproves a cached inspection is recomputed once the model file changes.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: invalidate Explorer caches when model source changes",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T04:51:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "01df1593ae93fbe04234852763d6db99a046cff8",
          "body": "…ng them\n\nRelationFinder discovered relations by invoking each candidate method on a\nblank model instance and silently discarding any that threw (via rescue()) or\nreturned a non-relation. A relation whose builder throws — e.g. a whereHas /\nconstraint closure that dereferences the query builder, or a\n[…]\ninderTest covering typed-throwing, untyped-throwing, and\nclean-alongside-throwing relations, with a ThrowingRelationModel fixture.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: report relations whose method throws on invoke instead of droppi…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T04:39:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "844763e6fc37fb932a436ac55e00abaf82125497",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: update composer description + keywords for rebrand and MCP",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T02:27:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "871d14f02c2cfd35c50ede83efe11e7b2ae1fd69",
          "body": "Update the human-readable product name in README, the docs site (title, hero,\nguide pages), Boost guidelines, the package class docblock, and the phpunit\ntestsuite label. Technical identifiers are intentionally unchanged: Composer\nslug, PHP namespace, config keys, env-var prefixes, the MCP server name, class\nnames, and the repo URL all stay the same, so this is non-breaking for v0.3.0\ninstalls.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "rebrand: 'Laravel Model Explorer' -> 'Model Explorer for Laravel'",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T02:22:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3ac80ae0b7aaa5d7ab5c5f0f125c77a7f51aee23",
          "body": null,
          "is_bot": false,
          "headline": "Update CHANGELOG",
          "author_name": "serpentblade",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T00:39:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dbb808e4f2d14f9f226c8e0968d00e95c977c5e7",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: clear changelog Unreleased ahead of v0.3.0 release",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T00:39:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "de99ba0339ecc8e2885edf0c46324debacf0b89d",
          "body": "… aside\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: clarify MCP model references; drop confusing base64url/HTTP-API…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-30T00:35:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "82312932960291923e6ae683ff5d40397f476d96",
          "body": null,
          "is_bot": false,
          "headline": "Fix styling",
          "author_name": "serpentblade",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:56:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9188e126af5b74d29c8e5d929ba6dec00396d06a",
          "body": "…attributes\n\nAdd a VitePress 'Model Introspection (MCP)' guide page (wired into the\nsidebar nav + home feature card + Getting Started cross-link) documenting\nthe five MCP tools, client registration, configuration, and live-by-default\nbehavior.\n\nClean up .gitattributes export-ignore rules so the Comp\n[…]\nesources/js, resources/css —\ncompiled output already ships in public/). Remove 8 stale entries for files\nnot present in this repo.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add MCP guide to docs site; chore: trim Packagist dist via .git…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:51:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "199a407d9931d98eabbe303b1b1f691fb7720766",
          "body": "…istency)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: post-review cleanup for MCP server (dead code, docblocks, cons…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:33:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7b6f91f0f12fa8defe4e40ffe7987dc9700addec",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: Boost guidelines + README/CHANGELOG for MCP server",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:22:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "252ebaccce8bcf75bc133e913eb4a7f4df04edee",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: register model-explorer MCP server with enabled/mcp.enabled gating",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:17:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ddbd038aa7179d6d9d15029e6f7856d8a3360666",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add model-source tool for on-demand snippets",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:11:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "15e3e28f8465ae9828d31b9bb0b69dc991244086",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add find-model tool with trait/extends/relatesTo/hasColumn filters",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T23:04:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "56146fa28ffa77fb485eba181733b87413e3344e",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add relationship-graph tool",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:59:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "05987180d37f6713670b039ec79182a86ef5f739",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add inspect-model tool with opt-in sections",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:54:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1a391a0535eb20fc300b101ca3b1ced63f06d368",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add ModelExplorerServer and list-models tool",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:39:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f6c8a1f739d0c5f9bd2fd01860ead679096c5805",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add CompactPresenter for AI-optimized model JSON",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:31:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e8f1103d3756a9abf793157d89f6fe5efb474e3",
          "body": null,
          "is_bot": false,
          "headline": "feat: add ModelResolver for MCP model-name resolution",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:23:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0cd5fd9ec9fc922eb5d9e1b56b2ada076963a04a",
          "body": null,
          "is_bot": false,
          "headline": "feat: add laravel/mcp dep, mcp config block, ExplorerCache::rememberWhen",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:19:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0d22146fed26752f8cc258c3d673cc67853ebcea",
          "body": null,
          "is_bot": false,
          "headline": "refactor: extract GraphBuilder from GraphController",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T22:13:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a196d34f803eca067d1c2262ef08e684595d0410",
          "body": "Eleven TDD tasks from ADR-011: GraphBuilder extraction, laravel/mcp dep +\nconfig + rememberWhen, ModelResolver, CompactPresenter, the five tools, server\nregistration with kill-switch gating, and Boost guidelines + docs.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: implementation plan for MCP model-introspection server",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T21:57:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9f908844daa59425eaa052299efdb996c0a0534b",
          "body": "Add the caching decision: the agent surface bypasses ExplorerCache and reads\nlive, independent of the HTTP cache.enabled setting, so an agent never reasons\non stale structure mid-development. Opt-in mcp.cache.enabled (default false)\ntrades freshness for speed on very large model sets. No per-call flag.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: ADR-011 — MCP tools read live by default",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T21:37:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2bcca5b3be688e561dffd8a8ee448960cad8267b",
          "body": "Records the decision to ship a laravel/mcp local server (model-explorer)\nexposing five introspection tools to AI agents, plus Boost guidelines for\ndiscovery. Boost itself has no package hook for live tools (laravel/boost#522),\nso a sibling MCP server is the supported path.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: ADR-011 for MCP model-introspection server",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T21:33:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "40c67655662f071e3a0fb7734ed0361c4173673f",
          "body": "Capture the one remaining suggestion from the v0.3.0 review (a paginated\n\"browse records\" mode for the record browser) under a Deferred / Future\nsection in ADR-009 so it isn't lost.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: record record-browse mode as a deferred follow-up",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T20:51:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6903b9ef89f8c40224553f55a28ed9857cbcb5de",
          "body": "Add the new config keys (excluded_models, per_page, cache) to the published\nconfig file, document them and the caching workflow in the README, record\nthe v0.3.0 changes in the CHANGELOG, mark the ADR-009 follow-ups done, and\ncorrect the documented PHP requirement to 8.3+ to match composer.json.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: publish config, README, CHANGELOG and ADR for v0.3.0",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T20:05:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "537acf3aa27fdeb88af0f0af1eebe975cfdb4112",
          "body": "Add an ExplorerCache service (no-op unless model-explorer.cache.enabled)\nwrapping the model list, detail, and graph endpoints. Invalidation uses a\nversioned key namespace so flush works on stores without tag support; the\ndetail cache key embeds the model file's mtime so editing a model refreshes\nit automatically. Adds the `model-explorer:clear` artisan command to flush.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: opt-in caching for discovery and inspection",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T20:04:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a9807ce7f7c7e944be23d2c7dc4913a0e5ba9ef4",
          "body": "The model list instantiated each discovered class inline, so a single model\nthat throws on construction broke the entire endpoint. Move the per-model\nsummary into summarize(), which returns null on failure and is filtered out.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(models): skip un-instantiable models in the list",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T20:04:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bd984a1a6850f00ea83ff4ba121617e59048c583",
          "body": "Replace the two hardcoded page sizes of 15 with a `model-explorer.per_page`\nconfig value (guarded to fall back to 15 when misconfigured), controlling\nboth to-many relation pagination and the cap on collection-returning\naccessor values.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(records): make relation/accessor page size configurable",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T20:03:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "12878872ca54a0395d224a4371bf79fe4d398ab6",
          "body": "withinSafeRead() always wrapped its rolled-back transaction in the default\nconnection, so accessor/observer writes on a model that uses a non-default\nconnection were not rolled back. Resolve the model's own connection and\nopen the transaction there instead.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(records): open safe-read transaction on the model's connection",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T20:01:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b5f02a0a0d829699c61f741fb7a5c6e6f2ddd639",
          "body": "FK badges in the Columns table now link to the related model's detail page\nwhen that model exists in the discovered set. ModelDetail fetches the model\nlist once and passes the known-class set to ColumnsTable; FKs whose related\nmodel is not discovered (or are polymorphic) render as a plain badge.\n\nIncludes the rebuilt public/ assets.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): link FK columns to the related model",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T19:59:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d1b85d877c030445beaa85366570ab45a5ce3582",
          "body": "Add an optional `model-explorer.excluded_models` config key so consumers\ncan hide specific model classes (Telescope, Passport, Horizon, etc.) even\nwhen they live inside a scanned path. Patterns are matched against the FQCN\nvia Str::is() and may use `*` wildcards; leading backslashes are ignored.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(discovery): support excluded_models config",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T19:58:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cd7e75007fffc614eeeb70f5771a445c0b9bbf01",
          "body": "CLAUDE.md is local developer/AI context and shouldn't live in version\ncontrol. Remove it from tracking and add it to .gitignore.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: stop tracking CLAUDE.md",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T19:58:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b3624856716757591e3bcbe968300fda9f8f3f25",
          "body": "Inject the Cloudflare Insights beacon script into the VitePress config head to enable analytics for the documentation site.",
          "is_bot": false,
          "headline": "docs: add Cloudflare Web Analytics beacon to docs site",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-29T16:56:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "398470278e9ee8de4f016512c7336efe7093d5ba",
          "body": "…ctions/actions/checkout-7\n\nchore(deps): bump actions/checkout from 6 to 7",
          "is_bot": false,
          "headline": "Merge pull request #8 from One-Learning-Community/dependabot/github_a…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-06-27T06:01:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b1ab62d92f97fd7a9a11aa059d63b88d91edd017",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/v6...v7)\n\n---\nupdated-dependenc\n[…]\n:\n- dependency-name: actions/checkout\n  dependency-version: '7'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump actions/checkout from 6 to 7",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-19T00:43:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a9c1a50b9a2d06910add035279a3d63427ef4b4",
          "body": "…ctions/dependabot/fetch-metadata-3.1.0\n\nchore(deps): bump dependabot/fetch-metadata from 3.0.0 to 3.1.0",
          "is_bot": true,
          "headline": "Merge pull request #7 from One-Learning-Community/dependabot/github_a…",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-04-24T00:45:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "272ba8844b1cc8da77327c68c98b4304f1553534",
          "body": "Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 3.0.0 to 3.1.0.\n- [Release notes](https://github.com/dependabot/fetch-metadata/releases)\n- [Commits](https://github.com/dependabot/fetch-metadata/compare/v3.0.0...v3.1.0)\n\n---\nupdated-dependencies:\n- dependency-name: dependabot/fetch-metadata\n  dependency-version: 3.1.0\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump dependabot/fetch-metadata from 3.0.0 to 3.1.0",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-04-24T00:45:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00a365484afce119c9d8c4a8d0467db9924044b1",
          "body": "…ctions/actions/upload-pages-artifact-5\n\nchore(deps): bump actions/upload-pages-artifact from 4 to 5",
          "is_bot": false,
          "headline": "Merge pull request #6 from One-Learning-Community/dependabot/github_a…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-04-17T04:03:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca017d7b9158a139bfd05bebf043bdcccb8338e6",
          "body": "Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 4 to 5.\n- [Release notes](https://github.com/actions/upload-pages-artifact/releases)\n- [Commits](https://github.com/actions/upload-pages-artifact/compare/v4...v5)\n\n---\nupdated-dependencies:\n- dependency-name: actions/upload-pages-artifact\n  dependency-version: '5'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump actions/upload-pages-artifact from 4 to 5",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-04-17T00:45:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9a04f8f8d5cfef655f9fc6c2d12d7158cf3d9ef",
          "body": "…ctions/actions/upload-pages-artifact-4\n\nchore(deps): bump actions/upload-pages-artifact from 3 to 4",
          "is_bot": false,
          "headline": "Merge pull request #1 from One-Learning-Community/dependabot/github_a…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-27T14:20:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "659964df8064f1d4afe59d7a04f190da740c5374",
          "body": "…ctions/actions/setup-node-6\n\nchore(deps): bump actions/setup-node from 4 to 6",
          "is_bot": false,
          "headline": "Merge pull request #2 from One-Learning-Community/dependabot/github_a…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-27T14:20:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83d1a04d5a892d6d1053bb8d57ff827bdea0a463",
          "body": "…ctions/actions/deploy-pages-5\n\nchore(deps): bump actions/deploy-pages from 4 to 5",
          "is_bot": false,
          "headline": "Merge pull request #3 from One-Learning-Community/dependabot/github_a…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-27T14:20:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6654faad63d9816d779b335d7c2d07752cbb698c",
          "body": "…ctions/dependabot/fetch-metadata-3.0.0\n\nchore(deps): bump dependabot/fetch-metadata from 2.5.0 to 3.0.0",
          "is_bot": false,
          "headline": "Merge pull request #4 from One-Learning-Community/dependabot/github_a…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-27T14:19:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3253e481f29c5f4372d7fcec85a06efa135daf5",
          "body": "…/orchestra/testbench-tw-11.0.0\n\nchore(deps-dev): update orchestra/testbench requirement from ^10.0.0||^9.0.0 to ^11.0.0",
          "is_bot": false,
          "headline": "Merge pull request #5 from One-Learning-Community/dependabot/composer…",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-27T14:19:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6283afbf750cbb3b842ba3af9c7d07b89bd8a15a",
          "body": "Updates the requirements on [orchestra/testbench](https://github.com/orchestral/testbench) to permit the latest version.\n- [Release notes](https://github.com/orchestral/testbench/releases)\n- [Changelog](https://github.com/orchestral/testbench/blob/11.x/CHANGELOG-10.x.md)\n- [Commits](https://github.c\n[…]\ns/v11.0.0)\n\n---\nupdated-dependencies:\n- dependency-name: orchestra/testbench\n  dependency-version: 11.0.0\n  dependency-type: direct:development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps-dev): update orchestra/testbench requirement",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-27T00:46:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1aef693c6db1e3b0c5aa0d28b9975951cb7f186d",
          "body": "Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.5.0 to 3.0.0.\n- [Release notes](https://github.com/dependabot/fetch-metadata/releases)\n- [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.5.0...v3.0.0)\n\n---\nupdated-dependencies:\n- dependency-name: dependabot/fetch-metadata\n  dependency-version: 3.0.0\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump dependabot/fetch-metadata from 2.5.0 to 3.0.0",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-27T00:45:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5d575fc7f2d11653fdbfe1ffcc14ddd73be02fc4",
          "body": "Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5.\n- [Release notes](https://github.com/actions/deploy-pages/releases)\n- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)\n\n---\nupdated-dependencies:\n- dependency-name: actions/deploy-pages\n  dependency-version: '5'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump actions/deploy-pages from 4 to 5",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-27T00:44:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "49114e77df8b35e80ee7ba2510ede74d59aa4b64",
          "body": "Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.\n- [Release notes](https://github.com/actions/setup-node/releases)\n- [Commits](https://github.com/actions/setup-node/compare/v4...v6)\n\n---\nupdated-dependencies:\n- dependency-name: actions/setup-node\n  dependency-version: '6'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump actions/setup-node from 4 to 6",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-27T00:44:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb35c9bde7cac84cfa292e1b0d19c4668bf99d7e",
          "body": "Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 3 to 4.\n- [Release notes](https://github.com/actions/upload-pages-artifact/releases)\n- [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v4)\n\n---\nupdated-dependencies:\n- dependency-name: actions/upload-pages-artifact\n  dependency-version: '4'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump actions/upload-pages-artifact from 3 to 4",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-27T00:44:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3e2882ba7dbcaf012687f3fbc392383733a8a48",
          "body": null,
          "is_bot": false,
          "headline": "Add screenshots to docs",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-26T05:03:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe151b15dab859a768cd592dd8890b72a319d34f",
          "body": null,
          "is_bot": false,
          "headline": "Update CHANGELOG",
          "author_name": "serpentblade",
          "author_login": "serpentblade",
          "committed_at": "2026-03-25T06:07:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0faa3b99b363824697edaa634e6cb53980d090e",
          "body": null,
          "is_bot": false,
          "headline": "Make table name searchable on model list",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-25T06:04:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "382ba46dfad22960722c4711910b207693c1e46c",
          "body": "Stop using ModelInfo::forModel as the only thing we need from that process is the attributes, the rest is unused and error-prone.  Directly call AttributeFinder instead.",
          "is_bot": false,
          "headline": "Bugfix for relations loading",
          "author_name": "Dan Krieger",
          "author_login": "serpentblade",
          "committed_at": "2026-03-25T06:02:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 8,
      "commits_last_year": 157,
      "latest_release_at": "2026-07-05T18:05:29Z",
      "latest_release_tag": "v0.5.0",
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 8,
      "days_since_latest_release": 16,
      "mean_days_between_releases": 14.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "onelearningcommunity/laravel-model-explorer",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "laravel",
            "models",
            "eloquent",
            "Developer tools",
            "ai",
            "mcp",
            "model-context-protocol"
          ],
          "ecosystem": "packagist",
          "matches_repo": true,
          "registry_url": "https://packagist.org/packages/onelearningcommunity/laravel-model-explorer",
          "is_deprecated": false,
          "latest_version": "v0.5.2",
          "repository_url": "https://github.com/One-Learning-Community/laravel-model-explorer",
          "versions_count": 10,
          "total_downloads": 28281,
          "dependents_count": 0,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 20899,
          "first_published_at": null,
          "latest_published_at": "2026-07-07T02:59:44Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 15
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 7,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 1
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 168434,
      "source_files_sampled": 101,
      "oversized_source_files": 1,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "composer.json",
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "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": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm",
        "packagist"
      ],
      "dependencies": [
        {
          "name": "illuminate/contracts",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^11.0||^12.0||^13.0"
        },
        {
          "name": "laravel/mcp",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^0.9.0"
        },
        {
          "name": "spatie/laravel-model-info",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^2.0"
        },
        {
          "name": "spatie/laravel-package-tools",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^1.16"
        },
        {
          "name": "lucide-vue-next",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.577.0"
        },
        {
          "name": "prismjs",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.30.0"
        },
        {
          "name": "vue",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.5"
        },
        {
          "name": "vue-router",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.6.4"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 1,
        "merged_prs": 9,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "serpentblade",
          "commits": 146,
          "avatar_url": "https://avatars.githubusercontent.com/u/1483665?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "dependabot-auto-merge.yml",
        "docs.yml",
        "fix-php-code-style-issues.yml",
        "run-tests.yml",
        "update-changelog.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": true,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "1 out of 1 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/28 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "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": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 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": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 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": "c81565e6424a37474d09050ccd4c119758580601",
        "ran_at": "2026-07-22T14:17:48Z",
        "aggregate_score": 5.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-17T00:45:27Z",
      "oldest_open_prs": [
        {
          "number": 9,
          "created_at": "2026-07-17T00:43:45Z",
          "last_comment_at": "2026-07-17T00:43:45Z",
          "last_comment_author": "dependabot"
        }
      ],
      "last_merged_pr_at": "2026-07-17T00:45:25Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/One-Learning-Community/laravel-model-explorer",
    "host": "github.com",
    "name": "laravel-model-explorer",
    "owner": "One-Learning-Community"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 62,
      "inputs": {
        "security": 51,
        "vitality": 82,
        "community": 37,
        "governance": 55,
        "engineering": 80
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 82,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "commits_last_year": 157,
              "human_commit_share": 0.89,
              "days_since_last_push": 5,
              "active_weeks_last_year": 8
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "8/52 weeks with commits",
                "points": 5.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "157 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 157
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 8,
              "latest_release_tag": "v0.5.0",
              "releases_from_tags": false,
              "days_since_latest_release": 16,
              "mean_days_between_releases": 14.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "8 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 16 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 16
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~14.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 14.7
                    }
                  }
                ],
                "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": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "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": 37,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "forks": 0,
              "stars": 7,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "7 stars",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "packages": [
                "onelearningcommunity/laravel-model-explorer"
              ],
              "dependents": 0,
              "ecosystems": "packagist",
              "total_downloads": 28281,
              "monthly_downloads": 20899
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "20,899 downloads/month across packagist",
                "points": 57.6,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 20899,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "0 packages depend on it",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "registry_dependents",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 55,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "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": 72,
            "inputs": {
              "merged_prs": 9,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "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": "9/9 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 9,
                      "decided": 9
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/28 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "One-Learning-Community",
              "public_repos": 27,
              "account_age_days": 2316
            },
            "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": "0 followers of One-Learning-Community",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "One-Learning-Community"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "27 public repos, account ~6 yr old",
                "points": 22.5,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 27
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 6
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "onelearningcommunity/laravel-model-explorer"
              ],
              "ecosystems": "packagist",
              "any_deprecated": false,
              "min_days_since_publish": 15
            },
            "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 15 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 15
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "10 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 80,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "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": "1 out of 1 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [
                "eloquent",
                "eloquent-orm-models",
                "laravel",
                "ai",
                "developer-tools",
                "laravel-package",
                "mcp",
                "model-context-protocol",
                "php",
                "vue"
              ],
              "has_wiki": false,
              "homepage": "https://one-learning-community.github.io/laravel-model-explorer/",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://one-learning-community.github.io/laravel-model-explorer/",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "10 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "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": "moderate",
        "name": "Security",
        "value": 51,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dangerous_workflow",
                    "packaging",
                    "pinned_dependencies",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 51,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 13,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 5,
              "scorecard_aggregate": 5.1
            },
            "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": "1 out of 1 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/28 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "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": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow 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": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "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": 1
            },
            "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": 46,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.888,
              "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": "79 of 89 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 79,
                      "sampled": 89
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "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": 56,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.67,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.09
            },
            "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": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "67 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 67,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "9 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 9,
                      "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": 54,
            "inputs": {
              "primary_language": "PHP",
              "largest_source_bytes": 168434,
              "source_files_sampled": 101,
              "oversized_source_files": 1
            },
            "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": "1/101 source files over 60KB",
                "points": 54.5,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 101,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T14:17:55.598530Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/o/One-Learning-Community/laravel-model-explorer.svg",
  "full_name": "One-Learning-Community/laravel-model-explorer",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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