Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-30 05:55 UTC

big-emotion / ferry

GitHub Actions–native agent pipeline that turns Jira column moves into reviewed draft PRs — no server, no daemon.

TypeScript · JavaScriptMIT★ 3 estrellas⑂ 1 forkdesde abr 2026Ver en GitHub ↗

big-emotion/ferry tiene un índice de salud de 68 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Engineering Quality (88/100) y la más baja, Community & Adoption (40/100). Se actualizó por última vez hace 1 día. Una sola persona concentra la mayor parte del trabajo reciente.

68
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.

68
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

BIG EMOTIONOrganización
1 seguidor6 repositorios públicosdesde abr 2025

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
npm@big-emotion/ferry1.2.0247337hace 8 díasferrygithub-actionsjiracliautomation

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 1 días
5.5/36Cadencia de commits — 8/52 semanas con commits
18/18Volumen de commits — 587 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_year587
human_commit_share0,91
days_since_last_push1
active_weeks_last_year8
Cómo se puntúa
27/27Publica versiones — 37 versiones publicadas
36/36Recencia de las versiones — última versión hace 8 días
27/27Cadencia de publicación — una versión cada ~0,4 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count37
latest_release_tagv1.2.0
releases_from_tagsno
days_since_latest_release8
mean_days_between_releases0,4
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?

40En riesgo · 18% del índice global
Cómo se puntúa
4.9/60Estrellas — 3 estrellas
0/25Forks — 1 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks1
stars3
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)
18/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_contributing
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
45.2/80Descargas mensuales — 2473 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@big-emotion/ferry
dependents
ecosystemsnpm
total_downloads
monthly_downloads2473
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

57Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
10.3/22.5Distribución de commits — el principal contribuyente firma el 54% de los commits
2.7/13.5Amplitud de contribuyentes — 2 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor1
contributors_sampled2
top_contributor_share0,54
Cómo se puntúa
45.3/46.8Resolución de issues — 97% de issues cerradas
35.7/38.3Aceptación de PR — 223/239 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs223
open_issues6
closed_issues179
issue_closed_ratio0,968
closed_unmerged_prs16
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
2.2/25Alcance del propietario — 1 seguidores de big-emotion
8.8/25Trayectoria — 6 repos públicos, cuenta de ~1 años
Datos de entrada utilizados
followers1
owner_typeOrganization
is_verified
owner_loginbig-emotion
public_repos6
account_age_days483
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 8 días
20/20Historial de versiones — 37 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@big-emotion/ferry
ecosystemsnpm
any_deprecatedno
min_days_since_publish8

Calidad de Ingeniería

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

88Excelente · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 6 flujo(s) de trabajo
24/24Pruebas presentes
16/16Configuración de linter — .eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js
0/9.6Hooks de pre-commit
6.4/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_configno

Documentación

85Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
10/10Topics — 5 topics
10/10Wiki
Datos de entrada utilizados
topicsautomation, cli, ferry, github-actions, jira
has_wiki
homepage
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?

69Moderado · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
3.8/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 5 out of 5 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/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
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
5/5Packaging — packaging workflow detected
3/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 6
5/5SAST — SAST tool is run on all commits
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
5.2/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 15 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate6,1
Excluidos de la puntuación (sin datos o no aplicable): signed_releases. Los pesos restantes se han renormalizado.
Cómo se puntúa
35/35Dependencias directas libres de avisos conocidos — ninguna dependencia directa tiene un aviso conocido
25/25Dependencias indirectas libres de avisos conocidos — ninguna dependencia indirecta tiene un aviso conocido
0/40Sin avisos pendientes — ningún aviso tiene fecha de publicación
Datos de entrada utilizados
sourceosv
advisories0
affected_packages0
assessed_packages159
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Excluidos de la puntuación (sin datos o no aplicable): Sin avisos pendientes. Los pesos restantes se han renormalizado. Se cotejó el cierre de dependencias en tiempo de ejecución de npm:@big-emotion/ferry@1.2.0 —lo que arrastra la instalación del paquete publicado—: 159 paquetes. No se analiza la alcanzabilidad.

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.

86Excelente · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — .claude-pr/CLAUDE.md, .github/copilot-instructions.md, CLAUDE.md
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 91 de 91 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share1
agent_instruction_files.claude-pr/CLAUDE.md, .github/copilot-instructions.md, CLAUDE.md
agent_instruction_max_bytes12.620
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
11/11Configuración de lint / formato — .eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js
11/11Verificación estática de tipos — .ferry/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .ferry/node_modules/@stablelib/base64/tsconfig.json, .ferry/node_modules/fast-uri/tsconfig.json, .ferry/node_modules/json-with-bigint/tsconfig.json, .ferry/node_modules/openai/src/tsconfig.json, .ferry/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-emit-audit/node_modules/json-with-bigint/tsconfig.json, .github/actions/ferry-envelope-validate/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-developer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-merger/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-merger/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/protobufjs/tsconfig.json, tsconfig.json
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 28 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
6/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 6
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_config
typecheck_configs.ferry/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .ferry/node_modules/@stablelib/base64/tsconfig.json, .ferry/node_modules/fast-uri/tsconfig.json, .ferry/node_modules/json-with-bigint/tsconfig.json, .ferry/node_modules/openai/src/tsconfig.json, .ferry/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-emit-audit/node_modules/json-with-bigint/tsconfig.json, .github/actions/ferry-envelope-validate/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-developer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-merger/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-merger/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/protobufjs/tsconfig.json, tsconfig.json
agent_commit_share0,28
toolchain_manifests
dependency_bot_commit_share0,09
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
53.1/55Tamaños de archivo manejables — 14/404 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes406.037
source_files_sampled404
oversized_source_files14
Cómo se puntúa
40/40Esquema de API (OpenAPI/GraphQL/proto) — .ferry/node_modules/protobufjs/google/api/annotations.proto, .ferry/node_modules/protobufjs/google/api/http.proto, .ferry/node_modules/protobufjs/google/protobuf/api.proto, .ferry/node_modules/protobufjs/google/protobuf/descriptor.proto, .ferry/node_modules/protobufjs/google/protobuf/source_context.proto, .ferry/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/type.proto
20/20Servidor MCP
40/40Ejemplos ejecutables — example, examples
Datos de entrada utilizados
example_dirsexample, examples
has_mcp_signal
api_schema_files.ferry/node_modules/protobufjs/google/api/annotations.proto, .ferry/node_modules/protobufjs/google/api/http.proto, .ferry/node_modules/protobufjs/google/protobuf/api.proto, .ferry/node_modules/protobufjs/google/protobuf/descriptor.proto, .ferry/node_modules/protobufjs/google/protobuf/source_context.proto, .ferry/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/type.proto

Datos clave

3estrellas de GitHub
2contribuidores
587commits en los últimos 12 meses
1días desde el último push
37versiones publicadas
1factor bus
6issues abiertas
npmecosistemas 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 6.1 / 10
6.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-30 05:54 UTC

10Binary-Artifactsno binaries found in the repo
5Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests5 out of 5 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/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
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
10Packagingpackaging workflow detected
6Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 6
10SASTSAST tool is run on all commits
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
7Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities15 existing vulnerabilities detected
Dependencias directas 16
RegistroPaqueteRestricción de versiónManifiesto
npmajv^8.0.0.ferry/package.json
npmajv-formats^3.0.1.ferry/package.json
npm@octokit/rest^22.0.1.ferry/package.json
npm@anthropic-ai/sdk^0.97.0.ferry/package.json
npm@google/genai^2.0.1.ferry/package.json
npmopenai^6.34.0.ferry/package.json
npmyaml^2.6.0.ferry/package.json
npm@anthropic-ai/sdk^0.97.0package.json
npm@google/genai^2.0.1package.json
npm@modelcontextprotocol/sdk^1.29.0package.json
npm@octokit/rest^22.0.1package.json
npmajv^8.0.0package.json
npmajv-formats^3.0.1package.json
npmopenai^6.34.0package.json
npmulid^3.0.2package.json
npmyaml^2.9.0package.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

Avisos de dependencias 0

Instalar npm:@big-emotion/ferry@1.2.0 arrastra 159 paquetes, directos y transitivos: 0 tienen avisos conocidos, de los cuales 0 son dependencias directas.

Ningún aviso conocido afecta a las dependencias evaluadas.

Un aviso significa que la versión registrada en el grafo de dependencias cae dentro del rango afectado de un aviso. No se analiza la alcanzabilidad, y el grafo incluye fijaciones de desarrollo y prueba: un hallazgo puede referirse al utillaje y no al software distribuido.

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "automation",
        "cli",
        "ferry",
        "github-actions",
        "jira"
      ],
      "is_fork": false,
      "size_kb": 15102,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "HTML": 4222,
        "Shell": 6681,
        "JavaScript": 950508,
        "TypeScript": 2019175
      },
      "pushed_at": "2026-07-28T19:03:31Z",
      "created_at": "2026-04-27T18:19:11Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-21T16:28:37Z",
      "description": "GitHub Actions–native agent pipeline that turns Jira column moves into reviewed draft PRs — no server,   no daemon.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript",
        "JavaScript"
      ]
    },
    "owner": {
      "blog": "https://big-emotion.com/",
      "name": "BIG EMOTION",
      "type": "Organization",
      "login": "big-emotion",
      "company": null,
      "location": "France",
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/205988443?v=4",
      "created_at": "2025-04-02T20:28:05Z",
      "is_verified": null,
      "public_repos": 6,
      "account_age_days": 483
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-07-21T16:16:33Z"
        },
        {
          "tag": "v1.1.2",
          "kind": "patch",
          "published_at": "2026-07-18T22:55:35Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2026-07-18T22:06:19Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-07-18T21:46:15Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2026-07-18T20:54:00Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2026-07-18T14:21:47Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2026-07-18T11:31:44Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2026-07-18T10:33:39Z"
        },
        {
          "tag": "v0.19.0",
          "kind": "minor",
          "published_at": "2026-07-18T09:27:40Z"
        },
        {
          "tag": "v0.18.2",
          "kind": "patch",
          "published_at": "2026-07-18T09:04:09Z"
        },
        {
          "tag": "v0.18.1",
          "kind": "patch",
          "published_at": "2026-07-18T08:03:59Z"
        },
        {
          "tag": "v0.18.0",
          "kind": "minor",
          "published_at": "2026-07-18T07:34:46Z"
        },
        {
          "tag": "v0.17.0",
          "kind": "minor",
          "published_at": "2026-06-07T12:05:03Z"
        },
        {
          "tag": "v0.16.0",
          "kind": "minor",
          "published_at": "2026-05-25T10:39:29Z"
        },
        {
          "tag": "v0.15.1",
          "kind": "patch",
          "published_at": "2026-05-21T19:07:50Z"
        },
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-05-21T16:04:29Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2026-05-21T14:06:04Z"
        },
        {
          "tag": "v0.13.2",
          "kind": "patch",
          "published_at": "2026-05-21T11:38:40Z"
        },
        {
          "tag": "v0.13.1",
          "kind": "patch",
          "published_at": "2026-05-20T23:52:35Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2026-05-20T21:46:12Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-05-20T00:33:11Z"
        },
        {
          "tag": "v0.10.3",
          "kind": "patch",
          "published_at": "2026-05-05T18:47:50Z"
        },
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-05-05T17:33:56Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-05-05T16:47:52Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-05-05T16:20:39Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-05-05T15:23:11Z"
        },
        {
          "tag": "v0.8.2",
          "kind": "patch",
          "published_at": "2026-05-05T14:55:22Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-05-05T14:35:21Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-05-05T13:24:32Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-05-04T21:18:52Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-05-04T18:10:40Z"
        },
        {
          "tag": "v0.5.3",
          "kind": "patch",
          "published_at": "2026-05-02T22:05:16Z"
        },
        {
          "tag": "v0.5.2",
          "kind": "patch",
          "published_at": "2026-05-02T21:27:25Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-05-02T20:40:30Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-05-02T17:52:14Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-05-02T11:28:41Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-05-01T15:32:15Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "c1138acb2407c1846fbc25544e6967a208a9655f",
          "body": "Re-audits the post-1.0.0 line at the v1.2.0 tip. Score holds at 8.9/10\nwith no P0 blockers. Coverage is now measured (87.3% statements /\n80.8% branches) rather than asserted, and the release-tag consistency\ntable is clean at @v1.2.0.\n\nRecords that a locally stale floating v1 tag is a fetch artifact, not a\nsupply-chain defect — verify it via git ls-remote, never git rev-parse.\n\nAdds a P2 note that Jira merge-column permissions became a security\nboundary under ADR-0005 rev. 2.",
          "is_bot": false,
          "headline": "docs: refresh production-readiness audit for v1.2.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-21T16:27:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "39a42f9f5607d22c38f453bb33212c0c94750486",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.2.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-21T16:08:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da35314c28135e80c540bcfc62181d6177e33d2e",
          "body": "…431)\n\nFive behaviors that consumers previously had to hand-write as\nprompts/<agent>.<path>.local.md overlays are now Ferry defaults on both\ndirect-action paths, so a fresh install behaves like a tuned one:\n\n- a `**Confidence (self-critique):** N/10` line on every audit comment\n- a PR label protocol\n[…]\nsrc/lib/prompts/agent-defaults.test.ts asserts these behaviors against the\nshipped prompt files so a later edit cannot silently demote one to opt-in.\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(agents): ship field-proven agent behavior as bundled defaults (#…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-21T13:52:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "12fed42ed3aa4fcf7b39637b89d81bb92965d5f2",
          "body": "Correct drift in CLAUDE.md against the current codebase:\n- document the build:cli bundle (dist/cli/) alongside build:ferry\n- add the Merger agent entrypoint\n- list the ferry-run-merger and ferry-run-claude-agent composites\n- describe all three execution paths (bundled script, claude-code, codex-cli)\n- expand the CLI bin inventory and point to docs/CLI.md\n- cover both shipped build artifacts in the Deployment section",
          "is_bot": false,
          "headline": "docs(claude-md): sync with current build, agents, and execution paths",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-19T15:33:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "010f15147572106521d72577a8d9b1a6485d9597",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.1.2",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T22:51:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb5c5fc260d78ab4176afe654a95fafcf3f4c135",
          "body": "Default Refiner, Reviewer, and Merger to claude-opus-4-8; Developer and\nIterator to claude-sonnet-5. Previously every agent fell back to\nclaude-sonnet-4-6 (and the script-path Developer default was\nclaude-opus-4-5).\n\n- config.ts: DEFAULT_FERRY_CONFIG.models per-agent defaults\n- ferry-init templates \n[…]\nte for Sonnet 5\n- reconcile.ts: Anthropic invoice name mappings for the two models\n- docs/CONFIGURATION.md and tests updated; .ferry/ bundles rebuilt\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "chore(config): set per-agent model tiers (Opus 4.8 + Sonnet 5) (#429)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-18T22:38:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "125ad0610026a6a9a5d932c761ffdb7d8229c5fa",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.1.1",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T22:03:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eae8df9f3ddbb469a51ac991429393436c4c11d1",
          "body": "Six source files load yaml at runtime via createRequire (config loading,\ndoctor checks, ferry-update's ferry.local.yml overrides). esbuild cannot\nbundle a dynamic require, so the module must resolve from the installed\npackage's node_modules — but yaml was declared in devDependencies, which\nnpx does \n[…]\ned in v1.0.1.\n\nVerified end-to-end: npm pack, install the tarball in a scratch project,\ncreateRequire('yaml') from the installed dist/cli/update/index.js\nresolves and parses a ferry.local.yml snippet.",
          "is_bot": false,
          "headline": "fix(packaging): declare yaml as a runtime dependency",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T22:00:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f21cd43087461384920669d77c01278a94e8ad23",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.1.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T21:37:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee60dbc49630bb3883accf953e75d2b21ab6dd68",
          "body": "Moving a ticket into workflow.agents.merger.trigger_column (default\n\"Ready to Merge\") now routes the generic ferry-transition event to the\nMerger, exactly like the four other agents' trigger columns. A column\nmove into the merge column is an explicit human merge order.\n\n- config: MergerWorkflowAgent\n[…]\nions bundles rebuilt\n\nThe Reviewer-emitted ferry-merge dispatch on approve is unchanged; the\ncolumn is an additional trigger path. The gh-pr-merge deny-list for the\nfour non-merger roles is untouched.",
          "is_bot": false,
          "headline": "feat(router): column-triggered Merger — ADR-0005 rev. 2",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T21:31:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4aa7b5c655a7b7b39fb92cadf52037de6c1d69aa",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.0.3",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T20:49:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e5fa869a5f00f31a2bb50de917a8e2d94d1a73ec",
          "body": "The claude-code-action App installation token carries no Actions scope,\nso every gh run list / gh run view --log-failed call made by an agent\nreturns 403 (observed on the CHANSUP dry-run: the Developer labeled the\nPR ci-failing because CI was unreadable, and the Merger cannot verify\nthe green state \n[…]\nper FR32/ADR-0005).\n\nRequest actions:read via additional_permissions; the calling job must\ngrant the matching ceiling, which ferry-router.yml's run-agent job\nalready does (permissions: actions: read).",
          "is_bot": false,
          "headline": "fix(cc-agent): request actions:read so agents can read CI state (#428)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-18T20:35:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b370abfbe78ec1ae8052ee46ce7d6990e2587a3a",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.0.2",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T14:18:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "735b5aff2a5c77944d35a8e6375f979be785b5c1",
          "body": "…427)\n\nThe Merger is reached only by the ferry-merge event the Reviewer\ndispatches on approval (ADR-0005), so the merge run's actor is Ferry's\nClaude GitHub App (claude[bot]), never a human. anthropics/claude-code-action's\nhuman-actor gate rejects any bot actor unless it is in allowed_bots\n(default \n[…]\node-action step, allow-listing\nFerry's own bot only (not '*'; the action lower-cases and strips the\n[bot] suffix). Human-triggered roles are unaffected — allowed_bots is\nconsulted only for bot actors.",
          "is_bot": false,
          "headline": "fix(claude-code): allow-list Ferry's own bot so the Merger can run (#…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-18T14:07:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f95af326bbdd163043fff198a524cbb7967be4e7",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.0.1",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T11:28:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac6d5054b869cfa82a6536bc3349fc5870c61adb",
          "body": "…package\n\nscripts/build-cli.mjs hardcodes the esbuild entrypoint list and never\nincluded resolve-transition, local, or codex-config, so their dist/cli/\nbundles were never emitted despite being declared in package.json bin.\nOn the claude-code path this crashed the Developer/Reviewer/Iterator\nagents w\n[…]\n) with their mkdir/chmod, and record the fix under CHANGELOG\n[Unreleased].\n\nVerified: npm run build:cli emits all three; each binary runs (no 127);\nnpm pack --dry-run ships all three (total files 18).",
          "is_bot": false,
          "headline": "fix(build): bundle the three CLI binaries missing from the published …",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T11:17:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d5399c393421dfe0efa9cb87a0d5995848244f2c",
          "body": null,
          "is_bot": false,
          "headline": "release: v1.0.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T10:26:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e2b3fe4c4208767892e34ceae4c3511541ef6a2",
          "body": null,
          "is_bot": false,
          "headline": "docs: refresh production-readiness audit for v0.19.0 (cleared for 1.0.0)",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T10:19:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "226ee8e756f48b6ccf62f51e0cb43cd06587fb5a",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.19.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T09:21:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e986a95cabaed89e3a9b8ba425bebe59b1e4360",
          "body": "… list (FER-27)\n\nEvery ferry-router.yml run showed the same anonymous \"Ferry — Router\" title, so\nthree concurrent dispatches for different tickets were indistinguishable in the\nActions list. The agent role is only known after the route job, but the dispatch\nevent type, ticket key, and target status \n[…]\ne consumer example stub, and the repo's own dogfood\nworkflow (effective immediately — run-name lives in the workflow file, not the\ncomposite, so no release is needed for the dogfood board to show it).",
          "is_bot": false,
          "headline": "feat(router): add run-name identifying each router run in the Actions…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T09:12:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a82a0f06ea62c6abb64060f7a0eae773acd47b85",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.18.2",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T08:57:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a5b57cacfd885127d2cb648c5cd23bcab1cc691",
          "body": "…ublished package (FER-26)\n\nWhen Ferry dogfoods itself, the ferry-run-claude-agent composite runs in a\ncheckout of big-emotion/ferry — so `npx -p @big-emotion/ferry@<ver> <bin>`\nresolves the LOCAL package (whose dist/ is not built) and every bin comes back\n\"command not found\", killing the agent befo\n[…]\nackage from a neutral dir. The CLIs still read prompts/config from the repo\ncwd (--repo-root unchanged), so consumer prompt resolution is intact.\n\nGuarded by structural tests in install-guide.test.ts.",
          "is_bot": false,
          "headline": "fix(composite): isolate npx via --prefix so dogfooding resolves the p…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T08:51:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "afbba32ed97d1ee8a126e48c1f14fc86d6e92055",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.18.1",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T07:58:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cf9733ded084e44e68711bd4227cf5c6d3cbefe0",
          "body": "…es to .claude-code.local.md\n\nThe claude-code prompt resolver only appended prompts/<agent>.<path>.local.md\nwhen NO full prompts/<agent>.<path>.md override existed — so a repo that ships\nits bundled prompt SOURCE at prompts/<agent>.claude-code.md (Ferry dogfooding\nitself) silently shadowed its own .\n[…]\nonsumers (npm files = dist/cli only), so this stays\ndogfooding-local with no consumer impact. Takes effect for Ferry's own\ndogfooding once a release carrying this resolver ships and the pin is bumped.",
          "is_bot": false,
          "headline": "fix(prompts): always apply the .local.md overlay; move dogfooding rul…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T07:48:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0c70cd78e4217d35f40991b0610edd9beb91c245",
          "body": "…ER-1) (#426)\n\n- Delete .github/workflows/ferry-{refine,dev,review,iterate,merge}.yml (legacy\n  @v0.17.0 install from #424): the router subscribes to the same event types,\n  so keeping both would double-fire every dispatch, including ferry-merge.\n- Install .github/workflows/ferry-router.yml from the\n[…]\n swap would otherwise invalidate.\n- Give ferry-release an explicit pin policy for the installed dogfood router\n  (release-coupled, staged in Step 8).\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(dogfooding): swap the 5 legacy workflows for the router model (F…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-18T07:37:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "38da2fc63ac7e2053143eccb8ec33e3a4546bc7f",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.18.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T07:30:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "997be840c837cd1c4b000ecd29f538bc89497c7b",
          "body": "CI (npm Audit supply-chain gate) went red on newly-published high-severity\nadvisories against already-present transitive deps — ws and protobufjs (via\n@google/genai) and hono (via @modelcontextprotocol/sdk). `npm audit fix`\npatches all three within the existing semver ranges: package.json is\nunchanged, only the lockfile moves. Rebuilt .ferry/ + composite bundles so\nthe vendored SDK code matches. `npm run audit:ci` is clean (0 blocking).",
          "is_bot": false,
          "headline": "fix(deps): patch ws, protobufjs and hono transitive advisories",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T07:20:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9cf35adc0b6478f5f95b5af338f0b92532aa28a7",
          "body": "Completes the thin-install migration surface. ferry-doctor, ferry-update and\nferry-uninstall now understand both install models; docs and guard tests\ndescribe the router model accurately. Hardened by an adversarial review pass\n(14 findings, all addressed):\n\ndoctor\n- secrets: transition-id secrets ar\n[…]\ns\n  Done/Closed; auto_transition_done + FERRY_MERGE_DONE_TRANSITION_ID are\n  script-path); MIGRATIONS.md v0.17.x -> v0.18.0 router migration entry;\n  install-guide guards updated to pin the new claims",
          "is_bot": false,
          "headline": "feat(cli): align doctor/update/uninstall and docs with the router model",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-18T00:40:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2372a19279b59a16eccb7c0ca12c0e331ab5b746",
          "body": "…ngle Jira rule\n\nThe claude-code install collapses to: ONE router workflow (ferry-router.yml)\n+ ONE any-column Jira rule + ferry.config as the single source of truth.\n\n- new shared composite .github/actions/ferry-run-claude-agent: one\n  role-parameterized action absorbing branch resolution (ferry/<k\n[…]\nRRY_INTEGRATION_BRANCH from the repo default branch, updates banner\n  and next-steps; script/codex paths keep the per-agent stubs\n- legacy 5-stub generator untouched — existing installs stay supported",
          "is_bot": false,
          "headline": "feat(router): thin router workflow, shared claude-agent composite, si…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-17T23:58:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "caf6c671f2312895e164dcb74c3f8b504c43bbce",
          "body": "…o-resolve\n\nBackward-compatible groundwork for the thin-install model (one any-column\nJira rule -> one router workflow -> config as single source of truth). All\nof it ships dormant: existing 5-event installs behave identically.\n\n- event schema v1: add optional `to_status` and the `transition` phase \n[…]\n  ferry_merge_done_transition_id input/env (the stub-level FR32 gap)\n- ferry-resolve-transition: support `--agent merge --kind done`\n- rebuild .ferry/ and composite-action bundles (schema vendored 4x)",
          "is_bot": false,
          "headline": "feat(router): foundations for the single-rule router model + FR32 aut…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-17T23:49:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1cc0fbcd59756b2d00219d03e6dae7b1b511e790",
          "body": "…s on the claude-code path\n\nThe claude-code path still injects numeric Jira transition ids into the\nagent prompt from FERRY_*_TRANSITION_ID secrets. This CLI is the bridge that\nlets a workflow drop those secrets: it reads ferry.config.json, maps the\n(agent, kind) pair to the configured auto_transiti\n[…]\naccess\n- writes the id to $GITHUB_OUTPUT (or stdout)\n\nThe composite action (thick-composite slice) and the router workflow will\ncall this to remove the transition-ID secrets from the claude-code path.",
          "is_bot": false,
          "headline": "feat(cli): add ferry-resolve-transition to auto-resolve transition id…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-17T23:22:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a96ef54aba90cfe44490584c0f9373d42e060371",
          "body": "…ames\n\nConsumers no longer have to look up numeric Jira transition ids by hand.\nThe Developer, Reviewer and Iterator agents now resolve the transition id\nat runtime from the configured target status name\n(workflow.agents.*.auto_transition*), matching on the transition's target\nstatus (transition.to.\n[…]\nsite-action bundles\n\nFirst slice of the install-simplification initiative (auto-resolve\ntransitions). Merger auto-resolve and the claude-code resolve step follow\nin later slices; both reuse this core.",
          "is_bot": false,
          "headline": "feat(jira): auto-resolve workflow transition ids from config status n…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-07-17T23:10:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4728dac8d484086188bfa0e0c6fd2d2d05504228",
          "body": "…plate (#422)\n\n- .claude/skills: migrate ferry-release and ferry-audit from user level,\n  refreshed against the current repo (package name, released workflow\n  surface, v0.17.0 reference map, FR32 Merger); add ferry-spec and\n  ferry-ticket, adapted from the Grande Chancellerie consumer skills\n- docs\n[…]\n- docs/templates: self-sufficient Jira ticket template for FER\n- .gitignore: version only the four ferry-* skills; local skill packs\n  stay untracked\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(skills): add project skills, spec bootstrap, and Jira ticket tem…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-17T22:22:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ab83b3ee750d79fdd8a6c5a813b1f9d47d70a9bb",
          "body": "After createPR, the Developer looks up the open PR for its working\nbranch and adds the ferry:reviewing label, surfacing pipeline status\nfrom the GitHub PR list. Best-effort by design: any lookup or labeling\nerror is logged as a warning and never fails the run or the FR18\ntransition.\n\n- src/agents/de\n[…]\nbest-effort call after createPR\n- .ferry/ and action bundles rebuilt in lock-step\n- .gitignore: ignore autogenerated .codex/ local environment config\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(developer): label opened PRs with ferry:reviewing (#423)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-17T22:22:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2b51a2e1bc9cf6886dcc83a9bd3e3d63092622dc",
          "body": "… (#424)\n\nWire big-emotion/ferry as a consumer of its own pipeline:\n\n- .github/workflows/ferry-{refine,dev,review,iterate,merge}.yml: the five\n  agent dispatch workflows, copied verbatim from the consumer stubs and\n  pinned to @v0.17.0 (only the copy-instruction header lines replaced;\n  ferry-merge'\n[…]\n awareness) — bundled defaults\n  untouched\n\nRemaining before first run (human): FER-5 secrets/variables, FER-6 board\ncolumns + Jira Automation rules.\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(dogfooding): install Ferry on its own repo (FER-3, FER-4, FER-7)…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-07-17T22:22:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "94188899feffee7d3834eef2da507a06397ab8de",
          "body": "Add operator-local Ferry runner CLI with poll and serve entrypoints, local idempotency persistence, per-ticket worktrees, package wiring, tests, and documentation.",
          "is_bot": false,
          "headline": "[codex] feat(local-runner): add operator-local CLI (#411)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-13T02:12:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d4d4b59315ae410c101f26381481a9dedbed18d",
          "body": "Co-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "Preserve local workflow and prompt overrides (#412)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-13T00:35:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d2893b8927cde26253215db7cc40c4611b9ad897",
          "body": "* add codex-cli workflow path\n\n* fix codex doctor typecheck\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "[codex] complete codex-cli execution path (#409)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-12T23:57:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da06698adc90b584044172bdab2acbc8a2111201",
          "body": "Co-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "docs(gitlab): add step-by-step install path (#407)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-12T23:41:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe7d111085ab03d462131dacd1bbf05342bac9b7",
          "body": "…de-code workflows (#397)\n\nCI-driving agents (Developer, Iterator, Merger) call `gh pr checks`,\n`gh run view --log-failed`, and the GraphQL statusCheckRollup to gate\ntransitions. Without `checks: read` and `actions: read`, GitHub returns\nHTTP 403 on all check-status endpoints, causing the agent to t\n[…]\nests so this\ncontract cannot silently drift again.\n\nFixes #395\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix(init): add checks: read + actions: read to dev/iterate/merge clau…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-10T21:04:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6f27868c781c6d92cfb0143afd5d00f35109b8ba",
          "body": "Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 17.0.5 to 17.0.7.\n- [Release notes](https://github.com/lint-staged/lint-staged/releases)\n- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/lint-staged/lint-staged/compar\n[…]\nrect:development\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump lint-staged from 17.0.5 to 17.0.7 (#399)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-09T06:00:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "03206012ee7afa0edf96bf9a63471b2d8d74184e",
          "body": "Bumps [@google/genai](https://github.com/googleapis/js-genai) from 2.6.0 to 2.8.0.\n- [Release notes](https://github.com/googleapis/js-genai/releases)\n- [Changelog](https://github.com/googleapis/js-genai/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/googleapis/js-genai/compare/v2.6.0...v2.8.\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump @google/genai from 2.6.0 to 2.8.0 (#401)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-09T06:00:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e0742749375300e183be4cbe143f4225a511c664",
          "body": "Bumps the typescript-toolchain group with 3 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) and [@typescript-eslint/parser](htt\n[…]\npdate:semver-minor\n  dependency-group: typescript-toolchain\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump the typescript-toolchain group with 3 updates (#398)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-09T05:59:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7265278223aa92e5fd55b36117c762794fc2b2e7",
          "body": "Bumps [openai](https://github.com/openai/openai-node) from 6.39.0 to 6.42.0.\n- [Release notes](https://github.com/openai/openai-node/releases)\n- [Changelog](https://github.com/openai/openai-node/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/openai/openai-node/compare/v6.39.0...v6.42.0)\n\n---\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump openai from 6.39.0 to 6.42.0 (#402)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-09T05:58:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db75a86fbf17c8cea4431a705f7daf4b7dde6b4d",
          "body": "…ion in agent jobs (#403)\n\nOn the claude-code path, dev/iterate/merge run-agent-claude-code jobs were\nmissing checks: read and actions: read, so every call to gh pr checks,\ngh run view, and the statusCheckRollup GraphQL endpoint returned HTTP 403.\nThe agent resolved CI as unknown and never transitio\n[…]\nterate script path already used\nfetch-depth: 0).\n\nCloses #396.\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix(claude-code): grant CI-read permissions and check out target vers…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-09T05:57:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8d5fcce14c839bad2e41c73840f13d39788c5016",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.17.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-06-07T11:59:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f040805709f5cae5925b302916b249870854fcdf",
          "body": "…gn merge docs (FR32)\n\nThe example consumer reviewer workflow (examples/consumer-setup/workflows/ferry-review.yml)\ngranted the script-path job only `contents: read`, so the FR32 `ferry-merge`\nrepository_dispatch on approve failed silently (the dispatch is best-effort, wrapped in\ntry/catch). ferry-in\n[…]\nated auto-transition) without\n  rewriting the historical decision\n- install-guide.test.ts: the test pinned the stale \"Ferry never merges\" string in\n  INSTALL.md; re-point it at the gated-merge wording",
          "is_bot": false,
          "headline": "fix(fr32): grant reviewer script-path contents:write in example + ali…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-06-07T11:31:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5c26acf361e33ceb726f045c88355d0ef88f75af",
          "body": "…t (#393)\n\n* feat(merger): implement src/agents/merger + merger role in ferry-agent\n\n- Add `merger` to `AgentRole` (run-agent.ts) and `AgentOutputRole` (cc-wrappers/routing.ts)\n- Add `merger` to `providerForRole` switch (always returns 'anthropic'; merger is script-only)\n- Add `mergePR(prRef, strate\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(merger): implement src/agents/merger + merger role in ferry-agen…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T10:49:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1d82d6313596568dc469ed1f5f48301ba5bfcf34",
          "body": "…390)\n\n- Add prompts/merge.claude-code.md and prompts/merge.codex-cli.md for\n  the direct-action execution paths (FR32 Merger)\n- Add prompts/merge.md for the script-path execution path\n- Extend CcAgent type, CC_AGENTS, and CC_PROMPT_TOKENS with 'merge'\n  (tokens: TICKET_KEY, RUN_ID — matches the fer\n[…]\nundled-default substitution and consumer override\n\nCloses #385\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(cc-prompt): add merge prompts + ferry-cc-prompt --agent merge (#…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T10:49:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b736451326870bf1cf288bdcb7ad1bad0a792920",
          "body": "* feat(refiner): MCP Phase 3 — migrate Refiner to agent-loop (issue #323)\n\nReplace single-shot createLlmCall with createAgentLoop + MCP plumbing.\nAdd FINISH_REFINE_TOOL (done) as the loop terminator, add runRefinerLoop()\nalongside the preserved runRefiner() for backward compatibility.\n\nCo-authored-b\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(refiner): MCP Phase 3 — migrate Refiner to agent-loop #323 (#394)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T10:49:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0db471bd3150c881ade51102c6a1431d8452d5fe",
          "body": "… (#391)\n\nRemove Bash(gh pr merge) and Bash(gh pr merge:*) from the Merger\nclaude-code path --disallowedTools, keeping Bash(gh pr close) blocked.\nAll four other roles (refiner, developer, reviewer, iterator) retain the\nfull ban. Mirrors the fix in examples/consumer-setup/workflows/ferry-merge.yml\nan\n[…]\ncaveat (label approval ≠ GitHub review approval).\n\nCloses #386\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(merger): allow gh pr merge for Merger role only (FR32, ADR-0005)…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T10:39:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d6be89583433e3b24d907b812a1baae01c607049",
          "body": "…g (#389)\n\n- Add .github/actions/ferry-run-merger/action.yml mirroring the other\n  ferry-run-* composites (inputs: payload, jira_*, *_api_key, github_token,\n  github_repo, ferry_merger_model; outputs: input_tokens, output_tokens,\n  cost_eur, model, cache_read_tokens, cache_write_tokens)\n- Wire merge\n[…]\n\n- Add merger to ROLES in scripts/smoke-bundle.sh\n\nCloses #384\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(actions): commit ferry-run-merger composite action + build wirin…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T10:39:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "943044e091108cc014c19dc7785040094fb30deb",
          "body": "Corrects documentation drift between described and actual Merger behaviour:\n\n- CHANGELOG [Unreleased]: trigger is `repository_dispatch: [ferry-merge]`\n  dispatched by the Reviewer, not the `ferry:approved` label; rename\n  FERRY_MERGE_MODEL/PROVIDER → FERRY_MERGER_MODEL/PROVIDER; fix\n  branch-protect\n[…]\nthe `ferry-merge` dispatch rather than the label.\n\nCloses #387\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "docs(fr32): align Merger docs with ferry-merge dispatch trigger (#392)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T10:39:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "37a4614e32e976f06178e77e47f953dd3e04c6ac",
          "body": "…t-loop (#381)\n\n* feat(reviewer): migrate from createToolCallLoop to createAgentLoop (MCP Phase 2, #322)\n\nReviewer now uses createAgentLoop so it inherits MCP wiring alongside\nDev and Iterator (part of #319).\n\nKey changes:\n- review-loop.ts: swap ToolCallLoop → AgentLoop; replace finish_review\n  with\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(reviewer): MCP Phase 2 — migrate Reviewer from tool-loop to agen…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T09:53:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "18e155909da82328b192cc6da8cc07abe922bb03",
          "body": "…NFIGURATION (#377)\n\n* docs(fr32): document Merger agent — MIGRATIONS, CHANGELOG, README, CONFIGURATION\n\nAdd consumer-facing documentation for the new Merger agent (FR32):\n\n- MIGRATIONS.md: v0.16.x → v0.17.0 entry covering ferry-merge.yml,\n  the optional FERRY_MERGE_DONE_TRANSITION_ID secret, and th\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "docs(fr32): document Merger agent — MIGRATIONS, CHANGELOG, README, CO…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T09:52:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "901488074211dd1a378be315c4910cea34a9eb2d",
          "body": "* feat(fr32): dispatch ferry-merge from cc-path reviewer on approve\n\nOn the claude-code execution path the reviewer now emits a\n`ferry-merge` repository_dispatch event whenever the verdict is\nApproved (FR32). This fixes the gap where cc-path consumers could\napprove a PR but the Merger agent never tr\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(fr32): dispatch ferry-merge from cc-path reviewer on approve (#378)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T09:52:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d9d76697815726e76ba9963392790c41bb73df94",
          "body": "…ry-merge dispatch (#379)\n\n* fix(FR32): reviewer script-path gets contents:write + best-effort ferry-merge dispatch\n\n- Add `merge` to EventPhase, event schema enum, and PHASE_TO_WORKFLOW routing\n- Fix ferry-review.yml run-agent permissions: contents:read → contents:write\n  (repository_dispatch requi\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix(FR32): reviewer script-path gets contents:write + best-effort fer…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T09:49:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "98d2701a2e6ada915fbec215ffbdb97d4b2cbe33",
          "body": "Adds a `ferry.local.yml` file that consumers can place at their repo root\nto declare workflow overrides that survive `ferry-update`. The file is\nread during regeneration so the resulting workflow files are deterministic\nfrom `(ferry version, ferry.local.yml)` — making `--dry-run` diffs\nmeaningful ag\n[…]\n/CONFIGURATION.md`: new \"Local overrides\" section\n\nCloses #371\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(update): introduce ferry.local.yml consumer-side overlay (#380)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-07T09:49:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9efbee7362d7b01a7db0ddbb7869cddf2cb8f305",
          "body": "Bumps [@google/genai](https://github.com/googleapis/js-genai) from 2.4.0 to 2.6.0.\n- [Release notes](https://github.com/googleapis/js-genai/releases)\n- [Changelog](https://github.com/googleapis/js-genai/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/googleapis/js-genai/compare/v2.4.0...v2.6.\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump @google/genai from 2.4.0 to 2.6.0 (#368)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-06T09:58:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "607278824b6a4faf82d5604eeb52b0ff4fa2d173",
          "body": "Bumps [openai](https://github.com/openai/openai-node) from 6.38.0 to 6.39.0.\n- [Release notes](https://github.com/openai/openai-node/releases)\n- [Changelog](https://github.com/openai/openai-node/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/openai/openai-node/compare/v6.38.0...v6.39.0)\n\n-\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump openai from 6.38.0 to 6.39.0 (#370)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-06T09:58:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4a78627f2e478fe4313e4738419864d2770429b3",
          "body": "…ith 6 updates (#373)\n\nBumps the typescript-toolchain group with 5 updates in the / directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.0` | `25.9.1` |\n| [@typescript-eslint/eslint-plugin](https://gi\n[…]\npdate:semver-patch\n  dependency-group: typescript-toolchain\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump the typescript-toolchain group across 1 directory w…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-06T09:58:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "83534c9ff28776ef97fe976043fa89a1ff4d6290",
          "body": "…bels, prompts and CLI support (#372)\n\n* feat(codex): add codex-cli routing and prompts\n\n* fix(codex-cli): apply codex-cli execution path changes to ferry-run-* action bundles\n\nThe ferry-run-{developer,iterator,refiner,reviewer} agent.js bundles were\nmissed in the previous commit — they still rejected codex-cli as a valid\nexecution_path and lacked the executionPath override plumbing.\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "Add 'codex-cli' execution path (openai/codex-action) with routing, la…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-06-06T09:57:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b5238ccfeb8545dd346e7fbff5fc84305e18fa03",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.16.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-25T10:36:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "85737814003c1d45550f3218a33216e417a4959d",
          "body": "…l (#365)\n\nReplace hardcoded `runs-on: ubuntu-latest` across all four agent workflow\ntemplates with `${{ fromJSON(vars.FERRY_RUNNER || '\"ubuntu-latest\"') }}`.\nConsumers on self-hosted runners set FERRY_RUNNER to a JSON string (e.g.\n'\"ubuntu-latest\"') or array (e.g. '[\"self-hosted\",\"Linux\",\"X64\"]') a\n[…]\nd documents the new variable in CONFIGURATION.md.\n\nCloses #364\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(init): support FERRY_RUNNER variable for self-hosted runner labe…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-25T10:15:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c55e466910f2baa7857896f5a347f95ef5ebb9ea",
          "body": "* feat(claude-code): resolve agent prompts via ferry-cc-prompt\n\nAdd ferry-cc-prompt, a bin that resolves the claude-code-path system prompt for each agent: the consumer's prompts/<agent>.claude-code.md override when present, otherwise Ferry's bundled default, with runtime token substitution. The fou\n[…]\n>\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(claude-code): resolve agent prompts via ferry-cc-prompt (#363)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-22T20:51:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c72179c747f1d4cd704f2a246a127579554987ac",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.15.1",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T19:05:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "596a4be8008c103b6453466d044f8d7e93028724",
          "body": "The four claude-code agent workflows were scaffolded with\n--permission-mode acceptEdits, which only auto-approves file edits. In a\nnon-interactive (SDK) run there is no human to grant permission, so every\nJira MCP tool call (and Bash/git/gh) is denied — the agent finishes with\npermission denials and\n[…]\nose`, so\nFerry's \"never merges\" guardrail is preserved.\n\nUpdate templates.test.ts to assert bypassPermissions and reject a\nregression to acceptEdits.\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "fix(init): scaffold claude-code workflows with bypassPermissions (#362)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-21T18:48:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "85e9e4eb4057a933d793be8de11c6f7520b2dbf4",
          "body": "…versions",
          "is_bot": false,
          "headline": "fix(deps): bump brace-expansion, fast-uri, protobufjs, ws to patched …",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T16:08:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95ceb32ca41037b6a8347d0fcb6157873392fe7a",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.15.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T16:01:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "78c9fcf64a446f9b3bd60060fe24189c0793707c",
          "body": "…n call (#361)\n\n* feat(claude-code): replace cc wrapper with a direct claude-code-action call\n\nFor `ferry:claude-code` tickets, each agent now runs as one direct\nanthropics/claude-code-action call instead of the\nferry-cc-prepare -> claude-code-action -> ferry-cc-apply wrapper. The\nagent does its own\n[…]\n failed\ntransition stays non-fatal but now emits a workflow warning annotation\nand a job-summary line instead of being silently swallowed.\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(claude-code): replace cc wrapper with a direct claude-code-actio…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-21T15:48:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "71e791bc61bd491dffc1c7f3ae38467bc276912b",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.14.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T14:03:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9fe550d662b1db88b8c967abf598a35fb06c3e92",
          "body": "…sks (#360)\n\nThe claude-code execution path for the refiner was broken end-to-end:\nclaude-code-action terminated successfully without writing\n.ferry/cc-output.json, so ferry-cc-apply failed with ENOENT — and even\nwith the artifact present, three refiner schemas disagreed and nothing\ncreated the Jira\n[…]\ntOutput variant (schema, types, contract,\n  FERRY_SUBTASK_COUNT plumbing) — the refiner no longer flows through\n  validateAgentOutput/decideContract.\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "fix(cc-refiner): make the claude-code-path refiner create Jira sub-ta…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-21T13:40:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "38ce5dcf647fff5c72f60fbeebfe2074d6731b55",
          "body": "…(#359)\n\n* feat(templates): expose claude-code session logs via upload-artifact\n\nAdds an observability bracket around the Run claude-code-action step in\nall four consumer workflow templates (refiner, developer, reviewer,\niterator). Each now:\n\n- Assigns id: cc-run so execution_file output is referenc\n[…]\n>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(templates): expose claude-code session logs via upload-artifact …",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-21T13:01:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "be6fe658694913bf6c9884d83ac5906aeb0262cb",
          "body": "The .ferry/ directory is gitignored wholesale; the six built action\nbundles are force-added so GitHub Actions can execute them on checkout.\nroute-action.js was the only bundle never added — its byte-identical\ndeployed copy lives at .github/actions/ferry-route/route-action.js.\nForce-add it for consistency with its six tracked siblings.",
          "is_bot": false,
          "headline": "build: commit the .ferry/route-action.js bundle",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T11:42:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79ce655fd99e99475b5af496e9023d48a3bece6a",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.13.2",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T11:35:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "98ddc0d6685b91e5ab4333928e26837a62059f19",
          "body": "…tem prompt via prompt input (#354)\n\ncc-prepare emitted claude_args as a JSON array, but claude-code-action@v1\nword-splits that input with shell-quote. A JSON array is mis-tokenized, so\nevery flag — including the Write(.ferry/cc-output.json) grant — was silently\ndropped. The refiner could not write \n[…]\nm(<role>). The system prompt is now folded into the action's\n  verbatim prompt: input, ahead of the initial prompt.\n- Amend ADR-0006 §2 and decisions/0002 for the prompt-delivery change.\n\nCloses #354.",
          "is_bot": false,
          "headline": "fix(cc-prepare): serialize claude_args as a shell string; deliver sys…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-21T11:26:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "496b9e26674adcd3a4038ae501af78f1c1dae041",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.13.1",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-20T23:49:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5042742647f2bb263bc715b7b721e377261740f5",
          "body": "* fix: add id-token: write to run-agent-claude-code jobs in all four templates\n\nanthropics/claude-code-action@v1 unconditionally calls core.getIDToken()\nduring setupGitHubToken. When a job has an explicit permissions: block that\nomits id-token, GitHub Actions denies the OIDC fetch and every consumer\n[…]\ns\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "fix: add id-token: write to claude-code workflow templates (#353) (#357)",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T23:35:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ab33a5ef44d73fafe169b9c3cb9019e23a7453da",
          "body": "…ED_PROMPTS_DIR (#356)\n\n* fix(cc-prepare): ship bundled prompts with action and set FERRY_BUNDLED_PROMPTS_DIR\n\nThe ferry-cc-prepare action claimed to be \"self-contained; no .ferry/ needed\"\nbut failed with ENOENT on the bundled prompt files because:\n\n1. build-ferry-actions.mjs copied prompts to ferry\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix(cc-prepare): ship bundled prompts with action and set FERRY_BUNDL…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T23:16:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2eb98f09f4ef2834ce1ef783ec8757e547518146",
          "body": "…s on claude-code path (#358)\n\n* fix(cc-prepare): add narrow Write(.ferry/cc-output.json) grant for read-only roles\n\nRefiner and reviewer agents on the claude-code path need to write their\nstructured result to .ferry/cc-output.json, but ROLE_ACCESS='read-only'\npreviously restricted --allowedTools to\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix: add narrow Write(.ferry/cc-output.json) grant for read-only role…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T22:58:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "314f8e9a821efdcd39232151013aeb9209d6c45f",
          "body": "…4/10)\n\nRefreshes docs/PRODUCTION-READINESS-AUDIT.md to reflect the v0.8.2 → v0.13.0\nwindow (8 releases). Overall score moves 8.2 → 8.4 (net +0.2).\n\nMovement:\n- Tests +0.5 (1200 → 2232 tests across 100 → 152 files)\n- CI/CD +0.5 (CodeQL fail-on-high/critical gate, gitlab-adapter job)\n- Consumer docs \n[…]\n finding tracked: SHA-pin the two repo-development helper workflows\nto match the project standard. Carry-overs unchanged (harden-runner egress\nallowlist, action 0d drift gate, e2e idempotency replay).",
          "is_bot": false,
          "headline": "docs(audit): refresh production-readiness audit for v0.13.0 (score 8.…",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-20T22:17:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9f8c564a778a233972018542266df252b581df50",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.13.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-20T21:43:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d881a439445978ec452396ccee88dbef68901563",
          "body": "…er/reviewer/iterator (closes #350) (#351)\n\n* feat(cc-prepare): complete role coverage for developer/reviewer/iterator (closes #350)\n\nThe ferry-cc-prepare composite entrypoint now dispatches into a per-role\nupstream-resolver for all four agents. Previously only the refiner role\nran end-to-end; the o\n[…]\ns soft-fail divergence) and 351-6 (test\nmock-architecture refactor) deferred — surfaced as needs-decision\nin the fix-train status comment.\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(cc-prepare): complete ferry-cc-prepare role coverage for develop…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T21:22:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e2366d49943d285c022acfb653b90a7fa51181b6",
          "body": "…dev/review/iterate fail-loud scaffold (refs #333) (#348)\n\n* feat(cc-wiring): wire claude-code-action four-step chain in workflows + templates (closes #333)\n\nReplace the fail-loud placeholder in every run-agent-claude-code job with the\nreal chain: checkout → ferry-cc-prepare → anthropics/claude-code\n[…]\n✅\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(cc-wiring): wire claude-code-action chain — refiner end-to-end, …",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T17:28:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e555a27fc3fad831f988d41272ea4e9e3d494fdf",
          "body": "…s (#303) (#349)\n\nWire the three no-auto-merge hardening primitives that previously had zero\ncallers into the claude-code execution path (ADR-0002 §accepted-divergences\npoints 3 & 4, ADR-0006 §5, #303).\n\n**tool-policy** (`claude-args.ts`):\n- Import `assertToolPolicyEnforcesNoAutoMerge` + `NO_AUTO_ME\n[…]\nrmissions checks; new §6 and §7 describe blocks.\n\nCloses #335.\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(hardening): wire secret-scan-gate + tool-policy + job-permission…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T14:06:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "99ccd97efe045d0c167c929848c3645ff39db982",
          "body": "… closes #331) (#347)\n\n* feat(cc-prepare): add ferry-cc-prepare composite action (ADR-0006 §2, #331)\n\nFront-half loader for the claude-code execution path. Runs BEFORE\n`anthropics/claude-code-action@v1` in the consumer workflow: reads the\nenvelope + ferry config + Jira issue, calls the per-role prep\n[…]\nL2: strict-proxy InMemoryTracker so non-getIssue calls throw\n- L3: refusal tests for developer/reviewer/iterator roles asserting #333 hint\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(cc-prepare): add ferry-cc-prepare composite action (ADR-0006 §2,…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T13:26:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e715f75ebbf4f731964b04a6013882005bc8ea71",
          "body": "…#328) (#346)\n\nREADME.md is reduced from 548 → 79 lines / ~30KB → 2.2KB, matching the\nclaude-code brevity standard. All removed content is preserved in new docs:\n\n- docs/INSTALL.md  — full install walkthrough (steps 1–4, SHA pinning, smoke\n                     test, ops setup, checklist)\n- docs/OVER\n[…]\nor all install-guide acceptance criteria. All 2088 tests pass.\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "docs(readme): trim README to 79 lines, move content to docs/ (closes …",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T12:35:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d4df635381bf08d801e991ef3192eaf0c3206ce2",
          "body": "…secret flow (#343)\n\n* feat(uninstall): remove new composite dirs and add interactive OAuth secret flow\n\n- Add `FERRY_COMPOSITE_DIRS` constant and `detectCompositeActions` / `removeCompositeActions`\n  to detect and delete `.github/actions/ferry-route/`, `ferry-cc-prepare/`, `ferry-cc-apply/`\n  as pa\n[…]\n.\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(uninstall): remove new composite dirs and add interactive OAuth …",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T11:18:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e7e5eda99983f7e0c34957e7f948f98c1f92265b",
          "body": "…2) (#344)\n\n* feat(cc-apply): add ferry-cc-apply composite action (ADR-0006 §2, #332)\n\nImplements the deterministic post-step for the claude-code execution path.\nReads .ferry/cc-output.json, validates fail-closed via AJV (NFR-S1), then\napplies Jira-side audit + transition writes (FR18/FR24/FR28) via\n[…]\n.\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(cc-apply): add ferry-cc-apply composite action (ADR-0006 §2, #33…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T11:18:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e5e8b1c39296c6d0bff6fe17d177104a202f4397",
          "body": "… functions (closes #330) (#345)\n\n* refactor(agent-runtime): extract per-role pre-loop setup into prepare functions (closes #330)\n\nEach agent today executes 60-100+ lines of stateful setup before\n`createAgentLoop`/`runReviewLoop`: Jira fetch, `buildSystem(<role>)`,\n`initialPrompt` builder, MCP capab\n[…]\nn tests in\n  iterator-prepare.test.ts and developer-prepare.test.ts covering the\n  hasLabelsConfig=true branch (the filtered subset path).\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "refactor(agent-runtime): extract per-role pre-loop setup into prepare…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T11:17:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "897cbdbea321bcbcda3dd3bd37d084d335893db2",
          "body": "…ider gate, workflow shape (#342)\n\nImplements three new `ferry-doctor` checks in `claude-code-path.ts` for\nconsumers using `execution_path: claude-code` (issue #336):\n\n- **CC path: token exclusivity** — red when `CLAUDE_CODE_OAUTH_TOKEN` is\n  absent as a repo secret; yellow when `ANTHROPIC_API_KEY` \n[…]\ne-positive behaviour for v0.12.x repos (acceptance criterion).\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(doctor): add claude-code path checks for token exclusivity, prov…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T09:46:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f68ff7798da9a61c5b967f809be5bb5bd9ad64fc",
          "body": "…ses #329) (#341)\n\n* feat(routing): enforce anthropicOnly as hard gate in resolveExecutionPath (issue #329)\n\nAdd a provider gate (step 2 in resolution order) that returns\n{ path: 'script', reason: 'provider-gate' } when anthropicOnly === false,\nbefore the per-ticket label override is consulted. This\n[…]\ned-by: jean-noe <jean-noe@users.noreply.github.com>\n\n---------\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat: enforce anthropicOnly as hard gate in resolveExecutionPath (clo…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T09:46:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "03e38810ec092a9ed67ec68ccede2b72358b8f3f",
          "body": "….12.x → v0.13.0 (#340)\n\nActivates the credential gate for the v0.12.x → v0.13.0 transition:\n- `ferry-update --dry-run` now reports the missing secret when running\n  from any v0.12.x base\n- Interactive `ferry-update` prompts for the token and sets it on the\n  repo; non-interactive stays on the scrip\n[…]\nt-out\n\nCloses #334. Refs ADR-0006 §7, decisions/0002 §G, #316.\n\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(migrations): add requires-secrets: CLAUDE_CODE_OAUTH_TOKEN to v0…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T09:45:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c61049f9a2c93c58f46071a378edf582126327ce",
          "body": "…ADR-0006 §3) (#327)\n\nAdds the routing decision step that the existing claude-code-path foundation\n(closed #300, #301, #302) was missing a workflow hook into. Until now, the\npure `resolveExecutionPath` resolver and `buildClaudeCodeJob` library had no\ncaller — no workflow ran them, so the path stayed\n[…]\nually flowing into a\nrunning workflow rather than living only in a unit-tested library.\n\nRefs ADR-0006 §3, ADR-0002 §wiring, closed #300, #301, #302.\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(routing): wire execution-path decision into consumer workflows (…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T01:07:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "be788b24986e12be228c4da5fa2a5703011e0e9a",
          "body": null,
          "is_bot": false,
          "headline": "release: v0.12.0",
          "author_name": "jean-noe",
          "author_login": "kooljo",
          "committed_at": "2026-05-20T00:22:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c2ebaa07815773bb4e430b02978125022cd98aed",
          "body": "…of #319) (#326)\n\n* docs(mcp): add Phase 0 reconnaissance for GitHub, Atlassian, Figma, Prismic MCP servers\n\nRead-only research output for epic #319 Phase 0 (#320). Documents per-server\nfindings on remote HTTP/SSE endpoint availability, headless authentication\nviability for GitHub Actions runners, a\n[…]\n cross-reference pointer to advertise the\n  Atlassian example (not the removed Figma one).\n\nAddresses the review-train blocker on this PR.\n\n---------\n\nCo-authored-by: jean-noe <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "docs(mcp): document GitHub, Atlassian, Prismic; defer Figma (Phase 1 …",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T00:12:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e13249857519dd7b33e3caa5d46698cf1fad178b",
          "body": "…ping (closes #302) (#314)\n\n* feat(claude-code): action job + prompt reuse + per-agent tool/MCP mapping (closes #302)\n\nStandalone, fully unit-tested mapping library for the claude-code-action\nexecution path (ADR-0006 / decisions/0002 §C). Pure and deterministic;\nconsumed later by the contract wrappe\n[…]\ntes cost_estimate against the strict RefinerCostEstimate shape so the\nclaude-code path cannot silently accept payloads the script path rejects.\n\n---------\n\nCo-authored-by: jnk <kollojeannoe@gmail.com>",
          "is_bot": false,
          "headline": "feat(claude-code): action job + prompt reuse + per-agent tool/MCP map…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T00:05:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c71a3a41fe18bc903e8d7315da77252d8685b339",
          "body": "…code contract decision (#301) (#313)\n\nAdds three explanatory comment blocks to `src/lib/cc-wrappers/contract.ts`\ncodifying the path divergences from the bundled-script implementation:\n\n- developer case (L141): the script's force/type-override `overrideNote`\n  suffix (`dev-action.ts:526-534`) is int\n[…]\nation (validator, decision\nfunction, idempotency-gated apply, schema) shipped in #315; this PR\ncontributes only the inline documentation that makes those accepted\ndivergences auditable in code review.",
          "is_bot": false,
          "headline": "docs(cc-wrappers): document accepted-divergence invariants in claude-…",
          "author_name": "jean-noe",
          "author_login": "jean-noe",
          "committed_at": "2026-05-20T00:05:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd449f93074336cbfebfd6f27ecb798e7dba902d",
          "body": "* chore(deps): bump @anthropic-ai/sdk from 0.95.2 to 0.97.0\n\nBumps [@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript) from 0.95.2 to 0.97.0.\n- [Release notes](https://github.com/anthropics/anthropic-sdk-typescript/releases)\n- [Changelog](https://github.com/anthropics/anthrop\n[…]\ngithub.com>\nCo-authored-by: jnk <jeannoe.kollo@big-emotion.com>\nCo-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>\nCo-authored-by: jean-noe <jean-noe@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump @anthropic-ai/sdk from 0.95.2 to 0.97.0 (#296)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T23:08:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6dd63ed2043a679a3a581dff92ba4060cb1354a5",
          "body": "Bumps [@google/genai](https://github.com/googleapis/js-genai) from 2.0.1 to 2.4.0.\n- [Release notes](https://github.com/googleapis/js-genai/releases)\n- [Changelog](https://github.com/googleapis/js-genai/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/googleapis/js-genai/compare/v2.0.1...v2.4.\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): bump @google/genai from 2.0.1 to 2.4.0 (#295)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T23:08:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 37,
      "commits_last_year": 587,
      "latest_release_at": "2026-07-21T16:16:33Z",
      "latest_release_tag": "v1.2.0",
      "releases_from_tags": false,
      "days_since_last_push": 1,
      "active_weeks_last_year": 8,
      "days_since_latest_release": 8,
      "mean_days_between_releases": 0.4
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 62,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@big-emotion/ferry",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "ferry",
            "github-actions",
            "jira",
            "cli",
            "automation"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@big-emotion/ferry",
          "is_deprecated": false,
          "latest_version": "1.2.0",
          "repository_url": "https://github.com/big-emotion/ferry",
          "versions_count": 37,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2473,
          "first_published_at": "2026-05-01T15:32:13.782000Z",
          "latest_published_at": "2026-07-21T16:16:32.331000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 8
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 3,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-04-27",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 16
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "example",
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [
        ".ferry/node_modules/protobufjs/google/api/annotations.proto",
        ".ferry/node_modules/protobufjs/google/api/http.proto",
        ".ferry/node_modules/protobufjs/google/protobuf/api.proto",
        ".ferry/node_modules/protobufjs/google/protobuf/descriptor.proto",
        ".ferry/node_modules/protobufjs/google/protobuf/source_context.proto",
        ".ferry/node_modules/protobufjs/google/protobuf/type.proto",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/google/api/annotations.proto",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/google/api/http.proto",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/api.proto",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/descriptor.proto",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/source_context.proto",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/type.proto",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/annotations.proto",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/http.proto",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/api.proto",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/descriptor.proto",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/source_context.proto",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/type.proto",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/google/api/annotations.proto",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/google/api/http.proto",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/api.proto",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/descriptor.proto",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/source_context.proto",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/type.proto",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/annotations.proto",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/http.proto",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/api.proto",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/descriptor.proto",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/source_context.proto",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/type.proto",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/annotations.proto",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/http.proto",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/api.proto",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/descriptor.proto",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/source_context.proto",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/type.proto"
      ],
      "has_devcontainer": false,
      "typecheck_configs": [
        ".ferry/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
        ".ferry/node_modules/@stablelib/base64/tsconfig.json",
        ".ferry/node_modules/fast-uri/tsconfig.json",
        ".ferry/node_modules/json-with-bigint/tsconfig.json",
        ".ferry/node_modules/openai/src/tsconfig.json",
        ".ferry/node_modules/protobufjs/tsconfig.json",
        ".github/actions/ferry-emit-audit/node_modules/json-with-bigint/tsconfig.json",
        ".github/actions/ferry-envelope-validate/node_modules/fast-uri/tsconfig.json",
        ".github/actions/ferry-run-developer/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
        ".github/actions/ferry-run-developer/node_modules/@stablelib/base64/tsconfig.json",
        ".github/actions/ferry-run-developer/node_modules/fast-uri/tsconfig.json",
        ".github/actions/ferry-run-developer/node_modules/openai/src/tsconfig.json",
        ".github/actions/ferry-run-developer/node_modules/protobufjs/tsconfig.json",
        ".github/actions/ferry-run-iterator/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
        ".github/actions/ferry-run-iterator/node_modules/@stablelib/base64/tsconfig.json",
        ".github/actions/ferry-run-iterator/node_modules/fast-uri/tsconfig.json",
        ".github/actions/ferry-run-iterator/node_modules/openai/src/tsconfig.json",
        ".github/actions/ferry-run-iterator/node_modules/protobufjs/tsconfig.json",
        ".github/actions/ferry-run-merger/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
        ".github/actions/ferry-run-merger/node_modules/@stablelib/base64/tsconfig.json",
        ".github/actions/ferry-run-merger/node_modules/fast-uri/tsconfig.json",
        ".github/actions/ferry-run-merger/node_modules/openai/src/tsconfig.json",
        ".github/actions/ferry-run-merger/node_modules/protobufjs/tsconfig.json",
        ".github/actions/ferry-run-refiner/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
        ".github/actions/ferry-run-refiner/node_modules/@stablelib/base64/tsconfig.json",
        ".github/actions/ferry-run-refiner/node_modules/fast-uri/tsconfig.json",
        ".github/actions/ferry-run-refiner/node_modules/openai/src/tsconfig.json",
        ".github/actions/ferry-run-refiner/node_modules/protobufjs/tsconfig.json",
        ".github/actions/ferry-run-reviewer/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
        ".github/actions/ferry-run-reviewer/node_modules/@stablelib/base64/tsconfig.json",
        ".github/actions/ferry-run-reviewer/node_modules/fast-uri/tsconfig.json",
        ".github/actions/ferry-run-reviewer/node_modules/openai/src/tsconfig.json",
        ".github/actions/ferry-run-reviewer/node_modules/protobufjs/tsconfig.json",
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 406037,
      "source_files_sampled": 404,
      "oversized_source_files": 14,
      "agent_instruction_files": [
        ".claude-pr/CLAUDE.md",
        ".github/copilot-instructions.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 12620
    },
    "dependencies": {
      "manifests": [
        ".ferry/package.json",
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 159,
        "malicious_count": 0,
        "assessed_package": "npm:@big-emotion/ferry@1.2.0",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "ajv",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.0.0"
        },
        {
          "name": "ajv-formats",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.0.1"
        },
        {
          "name": "@octokit/rest",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^22.0.1"
        },
        {
          "name": "@anthropic-ai/sdk",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.97.0"
        },
        {
          "name": "@google/genai",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.1"
        },
        {
          "name": "openai",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.34.0"
        },
        {
          "name": "yaml",
          "manifest": ".ferry/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.6.0"
        },
        {
          "name": "@anthropic-ai/sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.97.0"
        },
        {
          "name": "@google/genai",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.1"
        },
        {
          "name": "@modelcontextprotocol/sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.29.0"
        },
        {
          "name": "@octokit/rest",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^22.0.1"
        },
        {
          "name": "ajv",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.0.0"
        },
        {
          "name": "ajv-formats",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.0.1"
        },
        {
          "name": "openai",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.34.0"
        },
        {
          "name": "ulid",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.0.2"
        },
        {
          "name": "yaml",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.9.0"
        }
      ],
      "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": 10,
        "merged_prs": 223,
        "open_issues": 6,
        "closed_ratio": 0.968,
        "closed_issues": 179,
        "closed_unmerged_prs": 16
      },
      "bus_factor": 1,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "jean-noe",
          "commits": 259,
          "avatar_url": "https://avatars.githubusercontent.com/u/206253650?v=4"
        },
        {
          "type": "User",
          "login": "kooljo",
          "commits": 221,
          "avatar_url": "https://avatars.githubusercontent.com/u/17022476?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.54
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "claude-code-review.yml",
        "claude.yml",
        "codeql.yml",
        "ferry-ci.yml",
        "ferry-router.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".eslintrc",
        ".eslintrc.js",
        ".eslintrc.yml",
        "eslint.config.js"
      ],
      "has_editorconfig": true,
      "has_linter_config": true,
      "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": 5,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "5 out of 5 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/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "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": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 6,
            "reason": "dependency not pinned by hash detected -- score normalized to 6",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 10,
            "reason": "SAST tool is run on all commits",
            "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": 7,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "15 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "c1138acb2407c1846fbc25544e6967a208a9655f",
        "ran_at": "2026-07-30T05:54:56Z",
        "aggregate_score": 6.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": true,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-28T19:06:41Z",
      "oldest_open_prs": [
        {
          "number": 414,
          "created_at": "2026-06-15T22:36:31Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 416,
          "created_at": "2026-06-15T22:36:49Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 417,
          "created_at": "2026-06-22T22:34:52Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 418,
          "created_at": "2026-06-22T22:35:16Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 419,
          "created_at": "2026-06-22T22:35:37Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 421,
          "created_at": "2026-07-13T22:36:18Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 430,
          "created_at": "2026-07-20T22:35:21Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 432,
          "created_at": "2026-07-22T14:59:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 433,
          "created_at": "2026-07-22T15:26:20Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 434,
          "created_at": "2026-07-28T19:03:47Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-05-13T20:44:41Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 293,
          "created_at": "2026-05-15T21:08:18Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 324,
          "created_at": "2026-05-19T23:23:05Z",
          "last_comment_at": "2026-06-07T10:50:49Z",
          "last_comment_author": "claude"
        },
        {
          "number": 325,
          "created_at": "2026-05-19T23:35:25Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 404,
          "created_at": "2026-06-12T23:20:46Z",
          "last_comment_at": "2026-06-12T23:42:41Z",
          "last_comment_author": "jean-noe"
        },
        {
          "number": 405,
          "created_at": "2026-06-12T23:22:53Z",
          "last_comment_at": "2026-06-12T23:40:43Z",
          "last_comment_author": "jean-noe"
        },
        {
          "number": 425,
          "created_at": "2026-07-18T06:56:15Z",
          "last_comment_at": "2026-07-28T18:49:15Z",
          "last_comment_author": "github-actions"
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/big-emotion/ferry",
    "host": "github.com",
    "name": "ferry",
    "owner": "big-emotion"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 68,
      "inputs": {
        "security": 69,
        "vitality": 82,
        "community": 40,
        "governance": 57,
        "engineering": 88
      },
      "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": 587,
              "human_commit_share": 0.91,
              "days_since_last_push": 1,
              "active_weeks_last_year": 8
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "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": "587 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 587
                    }
                  }
                ],
                "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": 37,
              "latest_release_tag": "v1.2.0",
              "releases_from_tags": false,
              "days_since_latest_release": 8,
              "mean_days_between_releases": 0.4
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "37 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 37
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 8 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.4 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.4
                    }
                  }
                ],
                "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": 40,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 5,
            "inputs": {
              "forks": 1,
              "stars": 3,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "3 stars",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "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": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 56,
            "inputs": {
              "packages": [
                "@big-emotion/ferry"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2473
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,473 downloads/month across npm",
                "points": 45.2,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2473,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "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": 57,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 22,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.54
            },
            "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 54% of commits",
                "points": 10.3,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 54
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "merged_prs": 223,
              "open_issues": 6,
              "closed_issues": 179,
              "issue_closed_ratio": 0.968,
              "closed_unmerged_prs": 16
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "97% of issues closed",
                "points": 45.3,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 97
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "223/239 decided PRs merged",
                "points": 35.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 223,
                      "decided": 239
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 41,
            "inputs": {
              "followers": 1,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "big-emotion",
              "public_repos": 6,
              "account_age_days": 483
            },
            "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": "1 followers of big-emotion",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "big-emotion"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "6 public repos, account ~1 yr old",
                "points": 8.8,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 6
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 1
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@big-emotion/ferry"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 8
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 8 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "37 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 37
                    }
                  }
                ],
                "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": "excellent",
        "name": "Engineering Quality",
        "value": 88,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "excellent",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "6 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "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": ".eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js"
                    }
                  }
                ],
                "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": "5 out of 5 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": 85,
            "inputs": {
              "topics": [
                "automation",
                "cli",
                "ferry",
                "github-actions",
                "jira"
              ],
              "has_wiki": true,
              "homepage": null,
              "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "5 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 69,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 61,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 6.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 is not maximal on development and all release branches",
                "points": 3.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "5 out of 5 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/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "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 detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 6",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is run on all commits",
                "points": 5,
                "status": "met",
                "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": "detected GitHub workflow tokens with excessive permissions",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "15 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:@big-emotion/ferry@1.2.0 runtime dependency closure — what installing the published package pulls in — 159 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@big-emotion/ferry@1.2.0",
                  "assessed": 159
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 159,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 159,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "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": 2
            },
            "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": "excellent",
        "name": "AI Readiness",
        "value": 86,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                ".claude-pr/CLAUDE.md",
                ".github/copilot-instructions.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 12620
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".claude-pr/CLAUDE.md, .github/copilot-instructions.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".claude-pr/CLAUDE.md, .github/copilot-instructions.md, CLAUDE.md"
                    }
                  }
                ],
                "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": "91 of 91 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 91,
                      "sampled": 91
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                ".ferry/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
                ".ferry/node_modules/@stablelib/base64/tsconfig.json",
                ".ferry/node_modules/fast-uri/tsconfig.json",
                ".ferry/node_modules/json-with-bigint/tsconfig.json",
                ".ferry/node_modules/openai/src/tsconfig.json",
                ".ferry/node_modules/protobufjs/tsconfig.json",
                ".github/actions/ferry-emit-audit/node_modules/json-with-bigint/tsconfig.json",
                ".github/actions/ferry-envelope-validate/node_modules/fast-uri/tsconfig.json",
                ".github/actions/ferry-run-developer/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
                ".github/actions/ferry-run-developer/node_modules/@stablelib/base64/tsconfig.json",
                ".github/actions/ferry-run-developer/node_modules/fast-uri/tsconfig.json",
                ".github/actions/ferry-run-developer/node_modules/openai/src/tsconfig.json",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/tsconfig.json",
                ".github/actions/ferry-run-iterator/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
                ".github/actions/ferry-run-iterator/node_modules/@stablelib/base64/tsconfig.json",
                ".github/actions/ferry-run-iterator/node_modules/fast-uri/tsconfig.json",
                ".github/actions/ferry-run-iterator/node_modules/openai/src/tsconfig.json",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/tsconfig.json",
                ".github/actions/ferry-run-merger/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
                ".github/actions/ferry-run-merger/node_modules/@stablelib/base64/tsconfig.json",
                ".github/actions/ferry-run-merger/node_modules/fast-uri/tsconfig.json",
                ".github/actions/ferry-run-merger/node_modules/openai/src/tsconfig.json",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/tsconfig.json",
                ".github/actions/ferry-run-refiner/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
                ".github/actions/ferry-run-refiner/node_modules/@stablelib/base64/tsconfig.json",
                ".github/actions/ferry-run-refiner/node_modules/fast-uri/tsconfig.json",
                ".github/actions/ferry-run-refiner/node_modules/openai/src/tsconfig.json",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/tsconfig.json",
                ".github/actions/ferry-run-reviewer/node_modules/@anthropic-ai/sdk/src/tsconfig.json",
                ".github/actions/ferry-run-reviewer/node_modules/@stablelib/base64/tsconfig.json",
                ".github/actions/ferry-run-reviewer/node_modules/fast-uri/tsconfig.json",
                ".github/actions/ferry-run-reviewer/node_modules/openai/src/tsconfig.json",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/tsconfig.json",
                "tsconfig.json"
              ],
              "agent_commit_share": 0.28,
              "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": ".eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": ".ferry/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .ferry/node_modules/@stablelib/base64/tsconfig.json, .ferry/node_modules/fast-uri/tsconfig.json, .ferry/node_modules/json-with-bigint/tsconfig.json, .ferry/node_modules/openai/src/tsconfig.json, .ferry/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-emit-audit/node_modules/json-with-bigint/tsconfig.json, .github/actions/ferry-envelope-validate/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-developer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-merger/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-merger/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/protobufjs/tsconfig.json, tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".ferry/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .ferry/node_modules/@stablelib/base64/tsconfig.json, .ferry/node_modules/fast-uri/tsconfig.json, .ferry/node_modules/json-with-bigint/tsconfig.json, .ferry/node_modules/openai/src/tsconfig.json, .ferry/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-emit-audit/node_modules/json-with-bigint/tsconfig.json, .github/actions/ferry-envelope-validate/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-developer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-developer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-developer/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-iterator/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-merger/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-merger/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-merger/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-refiner/node_modules/protobufjs/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@anthropic-ai/sdk/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/@stablelib/base64/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/fast-uri/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/openai/src/tsconfig.json, .github/actions/ferry-run-reviewer/node_modules/protobufjs/tsconfig.json, tsconfig.json"
                    }
                  }
                ],
                "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": "28 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 28,
                      "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": "dependency not pinned by hash detected -- score normalized to 6",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 98,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 406037,
              "source_files_sampled": 404,
              "oversized_source_files": 14
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "14/404 source files over 60KB",
                "points": 53.1,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 404,
                      "oversized": 14
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "excellent",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "example_dirs": [
                "example",
                "examples"
              ],
              "has_mcp_signal": true,
              "api_schema_files": [
                ".ferry/node_modules/protobufjs/google/api/annotations.proto",
                ".ferry/node_modules/protobufjs/google/api/http.proto",
                ".ferry/node_modules/protobufjs/google/protobuf/api.proto",
                ".ferry/node_modules/protobufjs/google/protobuf/descriptor.proto",
                ".ferry/node_modules/protobufjs/google/protobuf/source_context.proto",
                ".ferry/node_modules/protobufjs/google/protobuf/type.proto",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/google/api/annotations.proto",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/google/api/http.proto",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/api.proto",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/descriptor.proto",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/source_context.proto",
                ".github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/type.proto",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/annotations.proto",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/http.proto",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/api.proto",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/descriptor.proto",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/source_context.proto",
                ".github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/type.proto",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/google/api/annotations.proto",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/google/api/http.proto",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/api.proto",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/descriptor.proto",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/source_context.proto",
                ".github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/type.proto",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/annotations.proto",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/http.proto",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/api.proto",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/descriptor.proto",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/source_context.proto",
                ".github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/type.proto",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/annotations.proto",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/http.proto",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/api.proto",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/descriptor.proto",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/source_context.proto",
                ".github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/type.proto"
              ]
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": ".ferry/node_modules/protobufjs/google/api/annotations.proto, .ferry/node_modules/protobufjs/google/api/http.proto, .ferry/node_modules/protobufjs/google/protobuf/api.proto, .ferry/node_modules/protobufjs/google/protobuf/descriptor.proto, .ferry/node_modules/protobufjs/google/protobuf/source_context.proto, .ferry/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/type.proto",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".ferry/node_modules/protobufjs/google/api/annotations.proto, .ferry/node_modules/protobufjs/google/api/http.proto, .ferry/node_modules/protobufjs/google/protobuf/api.proto, .ferry/node_modules/protobufjs/google/protobuf/descriptor.proto, .ferry/node_modules/protobufjs/google/protobuf/source_context.proto, .ferry/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-developer/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-iterator/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-merger/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-refiner/node_modules/protobufjs/google/protobuf/type.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/annotations.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/api/http.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/api.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/descriptor.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/source_context.proto, .github/actions/ferry-run-reviewer/node_modules/protobufjs/google/protobuf/type.proto"
                    }
                  }
                ],
                "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": "example, examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "example, examples"
                    }
                  }
                ],
                "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-30T05:55:25.722928Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/b/big-emotion/ferry.svg",
  "full_name": "big-emotion/ferry",
  "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.27.0 — metodología completa · wiki de métricas.

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