公开记录
软件健康报告模式 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年3月在 GitHub 上查看 ↗

One-Learning-Community/laravel-model-explorer 的健康指数为 100 分中的 62 分,处于「中等」区间。 其得分最高的类别是Vitality(82/100),最低的是Community & Adoption(37/100)。 最近一次更新在 5 天前。 近期的大部分工作由 1 位贡献者完成。

62
总分 / 100
中等

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 49(有风险)的上限。AI 就绪度不计入总体分。

62
优秀85-100堪称典范;基本满足所有检验标准
良好70-84健康;仅有轻微不足
中等50-69可接受,但存在明显不足;建议进行审查
存在风险30-49存在重大薄弱环节;采用时应保持审慎
危急1-29问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。

所有权

0 关注者27 个公开仓库始于 2020年3月

该仓库由组织支持——共同承担、可问责的托管责任,可延续于任何单一维护者之后。

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
Packagistonelearningcommunity/laravel-model-explorerv0.5.220,8991015 天前laravelmodelseloquentdeveloper-toolsaimcpmodel-context-protocol

按类别列示的指标

活力

项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?

82良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 5 天前
5.5/36提交节奏 — 52 周中有 8 周有提交
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

发布纪律

100优秀
评分方式
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

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template
评分方式
57.6/80月度下载量 — packagist 合计每月 20,899 次下载
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议题解决 — 没有议题或无数据
38.2/38.3PR 接受 — 已裁定的 PR 中 9/9 已合并
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
已排除计分(无数据或不适用):议题解决。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
0/25所有者影响力 — One-Learning-Community 有 0 位关注者
22.5/25既往记录 — 27 个公开仓库,账户约 6 年
所用输入
followers0
owner_typeOrganization
is_verified
owner_loginOne-Learning-Community
public_repos27
account_age_days2,316
评分方式
25/25已发布且可解析 — packagist 上有 1 个软件包
35/35发布时效 — 最近一次发布于 15 天前
20/20版本历史 — 10 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesonelearningcommunity/laravel-model-explorer
ecosystemspackagist
any_deprecated
min_days_since_publish15

工程质量

基础的工程与文档实践是否到位?

80良好 · 占总体的 20%

工程实践

74良好
评分方式
24/24CI 工作流 — 5 个工作流
24/24存在测试
0/16Linter 配置
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。 其余权重已重新归一化。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?这是一枚独立的实验性徽章——权重为 0.0,因此单独呈现,不影响总体健康评分。

46存在风险 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 89 次人类提交中有 79 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.888
agent_instruction_files
agent_instruction_max_bytes
评分方式
0/18一条命令的引导启动
22/22自动化测试
0/11Lint / 格式化配置
0/11静态类型检查
10/10可复现环境 — lockfile
10/10已体现的代理实践 — 最近 100 次提交中有 67 次由代理编写或署名代理
8/8自动化维护 — 最近 100 次提交中有 9 次为自动依赖更新
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可控的文件大小 — 采样的 101 个源文件中有 1 个超过 60KB
所用输入
primary_languagePHP
largest_source_bytes168,434
source_files_sampled101
oversized_source_files1
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
20/20MCP 服务器
0/40可运行示例
所用输入
example_dirs
has_mcp_signal
api_schema_files

关键数据

7GitHub 星标
1贡献者
157最近 12 个月提交数
5距最近推送天数
8发布版本数
1巴士系数(bus factor)
0开放议题
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.