Registro público
Informe de salud del softwareesquema 0.26.0 · métricas 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 estrellas⑂ 0 forksdesde mar 2026Ver en GitHub ↗

One-Learning-Community/laravel-model-explorer tiene un índice de salud de 62 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (82/100) y la más baja, Community & Adoption (37/100). Se actualizó por última vez hace 5 días. Una sola persona concentra la mayor parte del trabajo reciente.

62
global / 100
Moderado

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala de 1 a 100. El resultado global parte de su media; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe el límite 49 (En riesgo). Preparación para IA queda fuera.

62
Excelente85-100Ejemplar; cumple prácticamente todos los criterios evaluados
Bueno70-84Saludable; carencias menores
Moderado50-69Aceptable con carencias notables; se recomienda revisión
En riesgo30-49Debilidades significativas; su adopción exige cautela
Crítico1-29Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

Cada eje es una categoría. La forma importa más que la media: un proyecto sano llena toda la figura, mientras que un perfil de picos y cráteres indica que la fortaleza en una dimensión enmascara el riesgo en otra.

Titularidad

0 seguidores27 repositorios públicosdesde mar 2020

Este repositorio está respaldado por una organización: una custodia compartida y responsable que puede sobrevivir a cualquier mantenedor individual.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicaciónEtiquetas
Packagistonelearningcommunity/laravel-model-explorerv0.5.220.89910hace 15 díaslaravelmodelseloquentdeveloper-toolsaimcpmodel-context-protocol

Métricas por categoría

Vitalidad

¿Está vivo el proyecto: se escribe código y se publican versiones?

82Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 5 días
5.5/36Cadencia de commits — 8/52 semanas con commits
18/18Volumen de commits — 157 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year157
human_commit_share0,89
days_since_last_push5
active_weeks_last_year8
Cómo se puntúa
27/27Publica versiones — 8 versiones publicadas
36/36Recencia de las versiones — última versión hace 16 días
27/27Cadencia de publicación — una versión cada ~14,7 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count8
latest_release_tagv0.5.0
releases_from_tagsno
days_since_latest_release16
mean_days_between_releases14,7
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

¿Tiene el proyecto usuarios, descargas, atención y unas condiciones acogedoras para quienes contribuyen?

37En riesgo · 18% del índice global
Cómo se puntúa
12.6/60Estrellas — 7 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars7
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
0/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
57.6/80Descargas mensuales — 20.899 descargas/mes en packagist
0/20Dependientes en el registro — 0 paquetes dependen de él
Datos de entrada utilizados
packagesonelearningcommunity/laravel-model-explorer
dependents0
ecosystemspackagist
total_downloads28.281
monthly_downloads20.899

Sostenibilidad y Gobernanza

¿Sobrevivirá el proyecto a sus personas: factor bus, capacidad de respuesta, quién lo respalda y mantenimiento del paquete?

55Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
0/46.8Resolución de issues — sin issues o sin datos
38.2/38.3Aceptación de PR — 9/9 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/28 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs9
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues. Los pesos restantes se han renormalizado.
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
0/25Alcance del propietario — 0 seguidores de One-Learning-Community
22.5/25Trayectoria — 27 repos públicos, cuenta de ~6 años
Datos de entrada utilizados
followers0
owner_typeOrganization
is_verified
owner_loginOne-Learning-Community
public_repos27
account_age_days2316
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en packagist
35/35Recencia de publicación — última publicación hace 15 días
20/20Historial de versiones — 10 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesonelearningcommunity/laravel-model-explorer
ecosystemspackagist
any_deprecatedno
min_days_since_publish15

Calidad de Ingeniería

¿Existen unas prácticas mínimas de ingeniería y documentación?

80Bueno · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 5 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-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
Datos de entrada utilizados
has_ci
has_tests
has_editorconfig
has_linter_configno
has_precommit_configno

Documentación

90Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://one-learning-community.github.io/laravel-model-explorer/
10/10Descripción del repositorio
10/10Topics — 10 topics
0/10Wiki
Datos de entrada utilizados
topicseloquent, eloquent-orm-models, laravel, ai, developer-tools, laravel-package, mcp, model-context-protocol, php, vue
has_wikino
homepagehttps://one-learning-community.github.io/laravel-model-explorer/
has_readme
has_docs_dir
has_description

Seguridad

¿Son sólidas las prácticas visibles de seguridad y de cadena de suministro, sin exposición jurisdiccional de alto riesgo sin resolver?

51Moderado · 16% del índice global
Cómo se puntúa
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 — sin datos
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — 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 — sin datos
0/5Pinned-Dependencies — sin datos
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 — sin datos
0/7.5Token-Permissions — sin datos
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated13
scorecard_versionv5.5.0
checks_inconclusive5
scorecard_aggregate5,1
Excluidos de la puntuación (sin datos o no aplicable): dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions. Los pesos restantes se han renormalizado.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

46En riesgo · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 79 de 89 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,888
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
0/11Verificación estática de tipos
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 67 de los últimos 100 commits con autoría o crédito de agente
8/8Mantenimiento automatizado — 9 de los últimos 100 commits son actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — sin datos
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,67
toolchain_manifests
dependency_bot_commit_share0,09
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Pinned-Dependencies. Los pesos restantes se han renormalizado.
Cómo se puntúa
0/45Código verificable por tipos — PHP sin configuración de verificación de tipos
54.5/55Tamaños de archivo manejables — 1/101 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languagePHP
largest_source_bytes168.434
source_files_sampled101
oversized_source_files1
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
20/20Servidor MCP
0/40Ejemplos ejecutables
Datos de entrada utilizados
example_dirs
has_mcp_signal
api_schema_files

Datos clave

7estrellas de GitHub
1contribuidores
157commits en los últimos 12 meses
5días desde el último push
8versiones publicadas
1factor bus
0issues abiertas
npm, Packagistecosistemas de paquetes

Advertencias de recopilación de datos

  • 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

Más detalle

OpenSSF Scorecard 5.1 / 10
5.1agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).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
n/dDangerous-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
n/dPackagingpackaging workflow not detected
n/dPinned-Dependenciesno dependencies found
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
n/dToken-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
Dependencias directas 8
RegistroPaqueteRestricción de versiónManifiesto
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
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Informe JSON sin procesar legible por máquina
{
  "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"
}

Las puntuaciones son señales, no garantías. Reflejan prácticas públicamente visibles en GitHub; no son una auditoría de código ni una garantía de seguridad.

Los datos ausentes se excluyen y los pesos se renormalizan; nunca se puntúan como cero. La metodología es versionada y abierta: métricas v1.13.0, esquema v0.26.0 — metodología completa · wiki de métricas.

Cómo se sitúa un resultado dentro del registro general: estadísticas agregadasPackagist.