公开记录
软件健康报告模式 0.27.0 · 指标 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 星标⑂ 1 复刻始于 2026年4月在 GitHub 上查看 ↗

big-emotion/ferry 的健康指数为 100 分中的 68 分,处于「中等」区间。 其得分最高的类别是Engineering Quality(88/100),最低的是Community & Adoption(40/100)。 最近一次更新在 1 天前。 近期的大部分工作由 1 位贡献者完成。

68
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

1 关注者6 个公开仓库始于 2025年4月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
npm@big-emotion/ferry1.2.02,473378 天前ferrygithub-actionsjiracliautomation

按类别列示的指标

活力

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

82良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 1 天前
5.5/36提交节奏 — 52 周中有 8 周有提交
18/18提交量 — 最近一年 587 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year587
human_commit_share0.91
days_since_last_push1
active_weeks_last_year8

发布纪律

100优秀
评分方式
27/27有发布版本 — 已发布 37 个发布版本
36/36发布时效 — 最近一次发布版本于 8 天前
27/27发布节奏 — 约每 0.4 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count37
latest_release_tagv1.2.0
releases_from_tags
days_since_latest_release8
mean_days_between_releases0.4
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

40存在风险 · 占总体的 18%
评分方式
4.9/60星标 — 3 个星标
0/25复刻 — 1 个复刻
0/15关注者 — 0 位关注者
所用输入
forks1
stars3
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

70良好
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
18/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template
评分方式
45.2/80月度下载量 — npm 合计每月 2,473 次下载
0/20注册表被依赖数 — 该生态系统不报告此项
所用输入
packages@big-emotion/ferry
dependents
ecosystemsnpm
total_downloads
monthly_downloads2,473
已排除计分(无数据或不适用):注册表被依赖数。 其余权重已重新归一化。

可持续性与治理

项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?

57中等 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
10.3/22.5提交分布 — 头号贡献者编写了 54% 的提交
2.7/13.5贡献者广度 — 2 位贡献者
0/10OpenSSF Scorecard:Contributors — project has 0 contributing companies or organizations -- score normalized to 0
所用输入
bus_factor1
contributors_sampled2
top_contributor_share0.54
评分方式
45.3/46.8议题解决 — 97% 的议题已关闭
35.7/38.3PR 接受 — 已裁定的 PR 中 223/239 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs223
open_issues6
closed_issues179
issue_closed_ratio0.968
closed_unmerged_prs16
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
2.2/25所有者影响力 — big-emotion 有 1 位关注者
8.8/25既往记录 — 6 个公开仓库,账户约 1 年
所用输入
followers1
owner_typeOrganization
is_verified
owner_loginbig-emotion
public_repos6
account_age_days483
评分方式
25/25已发布且可解析 — npm 上有 1 个软件包
35/35发布时效 — 最近一次发布于 8 天前
20/20版本历史 — 37 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packages@big-emotion/ferry
ecosystemsnpm
any_deprecated
min_days_since_publish8

工程质量

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

88优秀 · 占总体的 20%

工程实践

90优秀
评分方式
24/24CI 工作流 — 6 个工作流
24/24存在测试
16/16Linter 配置 — .eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js
0/9.6Pre-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
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config

文档

85优秀
评分方式
30/30README
25/25文档目录
0/15文档 / 主页站点
10/10仓库描述
10/10主题标签 — 5 个主题标签
10/10Wiki
所用输入
topicsautomation, cli, ferry, github-actions, jira
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

69中等 · 占总体的 16%

安全态势

61中等
评分方式
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.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
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 — 无数据
5.2/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 15 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate6.1
已排除计分(无数据或不适用):signed_releases。 其余权重已重新归一化。
评分方式
35/35直接依赖不含已知公告 — 没有直接依赖携带已知公告
25/25间接依赖不含已知公告 — 没有间接依赖携带已知公告
0/40没有长期未处理的公告 — 没有公告带有发布日期
所用输入
sourceosv
advisories0
affected_packages0
assessed_packages159
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
已排除计分(无数据或不适用):没有长期未处理的公告。 其余权重已重新归一化。 比对的是 npm:@big-emotion/ferry@1.2.0 的运行时依赖闭包——安装已发布的软件包时真正被拉取进来的内容——共 159 个软件包。 未对可达性进行分析。

AI 就绪度

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

86优秀 · 占总体的 0%
评分方式
45/45代理指令 — .claude-pr/CLAUDE.md, .github/copilot-instructions.md, CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 91 次人类提交中有 91 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share1
agent_instruction_files.claude-pr/CLAUDE.md, .github/copilot-instructions.md, CLAUDE.md
agent_instruction_max_bytes12,620
评分方式
0/18一条命令的引导启动
22/22自动化测试
11/11Lint / 格式化配置 — .eslintrc, .eslintrc.js, .eslintrc.yml, eslint.config.js
11/11静态类型检查 — .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/10可复现环境 — lockfile
10/10已体现的代理实践 — 最近 100 次提交中有 28 次由代理编写或署名代理
8/8自动化维护 — 最近 100 次提交中有 9 次为自动依赖更新
6/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 6
所用输入
has_nix
has_tests
lockfilespackage-lock.json
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
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
评分方式
45/45可类型检查的代码 — TypeScript(静态类型)
53.1/55可控的文件大小 — 采样的 404 个源文件中有 14 个超过 60KB
所用输入
primary_languageTypeScript
largest_source_bytes406,037
source_files_sampled404
oversized_source_files14
评分方式
40/40API 模式(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/20MCP 服务器
40/40可运行示例 — example, examples
所用输入
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

关键数据

3GitHub 星标
2贡献者
587最近 12 个月提交数
1距最近推送天数
37发布版本数
1巴士系数(bus factor)
6开放议题
npm软件包生态系统数

数据采集警告

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

更多细节

OpenSSF Scorecard 6.1 / 10
6.1综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。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
不适用Signed-Releasesno releases found
7Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities15 existing vulnerabilities detected
直接依赖 16
注册表软件包版本约束清单文件
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
全部依赖 未采集

本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

依赖安全公告 0

安装 npm:@big-emotion/ferry@1.2.0 会引入 159 个包(直接与传递):其中 0 个存在已知公告,0 个为直接依赖。

没有已知公告影响已评估的依赖。

公告表示依赖图中记录的版本落入某条公告的受影响范围。可达性未经分析,且依赖图包含开发与测试的版本固定——某项发现可能只涉及工具链而非交付的软件。

原始 JSON 报告 机器可读
{
  "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"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v1.13.0、模式 v0.27.0—— 完整方法论 · 指标知识库.

单项结果在整体记录中的位置: 汇总统计npm.