公开记录
软件健康报告模式 0.26.0 · 指标 1.13.0 · 2026-07-22 11:08 UTC

aduermael / herm

Terminal-native AI coding agent running in containers.

Go · SwiftMIT★ 218 星标⑂ 9 复刻始于 2026年3月在 GitHub 上查看 ↗

aduermael/herm 的健康指数为 100 分中的 61 分,处于「中等」区间。 其得分最高的类别是Vitality(82/100),最低的是Security(46/100)。 最近一次更新在今天。 近期的大部分工作由 1 位贡献者完成。

61
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

Adrian Duermael个人账户
143 关注者75 个公开仓库始于 2014年2月shortcut.ai

该仓库由个人账户拥有。相较于组织支持的项目,单一所有者项目的延续性风险更高。

按类别列示的指标

活力

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

82良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 0 天前
13.2/36提交节奏 — 52 周中有 19 周有提交
18/18提交量 — 最近一年 956 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year956
human_commit_share1
days_since_last_push0
active_weeks_last_year19

发布纪律

90优秀
评分方式
27/27有发布版本 — 已发布 16 个发布版本
36/36发布时效 — 最近一次发布版本于 4 天前
27/27发布节奏 — 约每 10.1 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — Project has not signed or included provenance with any releases.
所用输入
releases_count16
latest_release_tagv0.8.7
releases_from_tags
days_since_latest_release4
mean_days_between_releases10.1

社区与采用

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

49存在风险 · 占总体的 18%

流行度与采用

49存在风险
评分方式
37.9/60星标 — 218 个星标
7.5/25复刻 — 9 个复刻
3.3/15关注者 — 5 位关注者
所用输入
forks9
stars218
watchers5
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template

可持续性与治理

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

46存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
1.9/22.5提交分布 — 头号贡献者编写了 91% 的提交
6.8/13.5贡献者广度 — 5 位贡献者
10/10OpenSSF Scorecard:Contributors — project has 4 contributing companies or organizations
所用输入
bus_factor1
contributors_sampled5
top_contributor_share0.914
评分方式
0/46.8议题解决 — 0% 的议题已关闭
34.6/38.3PR 接受 — 已裁定的 PR 中 75/83 已合并
15/15OpenSSF Scorecard:Code-Review — all changesets reviewed
所用输入
merged_prs75
open_issues15
closed_issues0
issue_closed_ratio0
closed_unmerged_prs8
评分方式
10/30所有权背书 — 个人(用户)账户
0/20已验证域名 — 不适用于个人账户
15.5/25所有者影响力 — aduermael 有 143 位关注者
25/25既往记录 — 75 个公开仓库,账户约 12 年
所用输入
followers143
owner_typeUser
is_verified
owner_loginaduermael
public_repos75
account_age_days4,530
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。

工程质量

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

81良好 · 占总体的 20%

工程实践

68中等
评分方式
24/24CI 工作流 — 5 个工作流
24/24存在测试
0/16Linter 配置
0/9.6Pre-commit 钩子
0/6.4.editorconfig
20/20OpenSSF Scorecard:CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config

文档

100优秀
评分方式
30/30README
25/25文档目录
15/15文档 / 主页站点 — https://hermagent.com
10/10仓库描述
10/10主题标签 — 6 个主题标签
10/10Wiki
所用输入
topicsai, ai-agents, coding-agent, containerization, sandbox, terminal
has_wiki
homepagehttps://hermagent.com
has_readme
has_docs_dir
has_description

安全

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

46存在风险 · 占总体的 16%

安全态势

46存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
3/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 30 out of 30 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
7.5/7.5Code-Review — all changesets reviewed
2.5/2.5Contributors — project has 4 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 32 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate4.6

AI 就绪度

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

78良好 · 占总体的 0%
评分方式
45/45代理指令 — prompts/container/tools/agent.md, prompts/cpsl/tools/agent.md, prompts/naked/tools/agent.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 87 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.87
agent_instruction_filesprompts/container/tools/agent.md, prompts/cpsl/tools/agent.md, prompts/naked/tools/agent.md
agent_instruction_max_bytes3,302
评分方式
12.6/18一条命令的引导启动 — go.mod, tools/ci-check/go.mod, tools/edit-file/go.mod(工具链约定,无任务运行器)
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — Go(静态类型)
10/10可复现环境 — Dockerfile, lockfile
10/10已体现的代理实践 — 最近 100 次提交中有 13 次由代理编写或署名代理
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilesgo.sum
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0.13
toolchain_manifestsgo.mod, tools/ci-check/go.mod, tools/edit-file/go.mod, tools/outline/go.mod, tools/write-file/go.mod
dependency_bot_commit_share0
评分方式
45/45可类型检查的代码 — Go(静态类型)
53.2/55可控的文件大小 — 采样的 241 个源文件中有 8 个超过 60KB
所用输入
primary_languageGo
largest_source_bytes182,845
source_files_sampled241
oversized_source_files8

关键数据

218GitHub 星标
5贡献者
956最近 12 个月提交数
0距最近推送天数
16发布版本数
1巴士系数(bus factor)
15开放议题
Go软件包生态系统数

数据采集警告

  • 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

更多细节

Star 与 Fork 历史 0 ★ / 9 ⇿
0Star
9Fork
14发布

每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。

3456789932026-032026-052026-07
主版本 0次版本 8修订 6
OpenSSF Scorecard 4.6 / 10
4.6综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-07-22 11:08 UTC

10Binary-Artifactsno binaries found in the repo
4Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
10Code-Reviewall changesets reviewed
10Contributorsproject has 4 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities32 existing vulnerabilities detected
直接依赖 6
注册表软件包版本约束清单文件
Gogithub.com/ebitengine/puregov0.10.1go.mod
Gogithub.com/google/uuidv1.6.0go.mod
Gogithub.com/rivo/unisegv0.4.7go.mod
Gogolang.org/x/termv0.40.0go.mod
Gogopkg.in/yaml.v3v3.0.1go.mod
Golangdag.com/langdagv0.10.0go.mod
全部依赖 未采集

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [
        "ai",
        "ai-agents",
        "coding-agent",
        "containerization",
        "sandbox",
        "terminal"
      ],
      "is_fork": false,
      "size_kb": 10458,
      "has_wiki": true,
      "homepage": "https://hermagent.com",
      "languages": {
        "C": 14163,
        "Go": 2199795,
        "CSS": 1366,
        "Shell": 187559,
        "Swift": 1034730,
        "Python": 2443,
        "Starlark": 5372,
        "Dockerfile": 756
      },
      "pushed_at": "2026-07-21T18:14:50Z",
      "created_at": "2026-03-03T16:16:24Z",
      "owner_type": "User",
      "updated_at": "2026-07-19T17:44:49Z",
      "description": "Terminal-native AI coding agent running in containers.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Go",
      "significant_languages": [
        "Go",
        "Swift"
      ]
    },
    "owner": {
      "blog": "https://x.com/aduermael",
      "name": "Adrian Duermael",
      "type": "User",
      "login": "aduermael",
      "company": "shortcut.ai",
      "location": "SF Bay Area",
      "followers": 143,
      "avatar_url": "https://avatars.githubusercontent.com/u/6775074?v=4",
      "created_at": "2014-02-24T19:43:47Z",
      "is_verified": null,
      "public_repos": 75,
      "account_age_days": 4530
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.8.7",
          "kind": "patch",
          "published_at": "2026-07-17T19:54:15Z"
        },
        {
          "tag": "v0.8.6",
          "kind": "patch",
          "published_at": "2026-07-08T21:09:08Z"
        },
        {
          "tag": "v0.8.5",
          "kind": "patch",
          "published_at": "2026-06-26T00:05:23Z"
        },
        {
          "tag": "v0.8.4",
          "kind": "patch",
          "published_at": "2026-06-24T17:55:25Z"
        },
        {
          "tag": "v0.8.3",
          "kind": "patch",
          "published_at": "2026-06-10T00:26:33Z"
        },
        {
          "tag": "v0.8.2",
          "kind": "patch",
          "published_at": "2026-06-04T00:09:08Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-05-26T18:21:01Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-05-21T18:28:57Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-05-05T03:55:04Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-04-17T17:19:54Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-04-07T17:27:40Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-03-28T02:05:24Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-03-24T20:52:03Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-03-20T18:03:56Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-03-20T02:23:09Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-03-17T17:16:00Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "f2da284547f6137553f8a84ab4ebd63069ff3287",
          "body": "* Polish Apple agent runtime and previews\n\n* Improve agent persistence and activity rows\n\n* Group agent activity timeline entries\n\n* Fix Apple concurrency warnings\n\n* Make file preview result nonisolated\n\n* Restore conversation drawer header",
          "is_bot": false,
          "headline": "Polish Apple agent runtime, previews, and conversations (#97)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-19T01:16:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "894287a592c0ab933859c358e681aa5e34bff3e3",
          "body": null,
          "is_bot": false,
          "headline": "Fix Pages deployment after release tags (#100)",
          "author_name": "Gaetan de Villele",
          "author_login": "gdevillele",
          "committed_at": "2026-07-18T04:46:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9fda190eadf31cc0456e0f679275e6a0be1960c8",
          "body": null,
          "is_bot": false,
          "headline": "Fix Pages deployment for release tags (#99)",
          "author_name": "Gaetan de Villele",
          "author_login": "gdevillele",
          "committed_at": "2026-07-17T21:52:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8e94d354e1ecccbf297753b1fa5babc787aeb637",
          "body": null,
          "is_bot": false,
          "headline": "update submodules (#98)",
          "author_name": "Gaetan de Villele",
          "author_login": "gdevillele",
          "committed_at": "2026-07-17T19:40:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b08537cbccf21268f6c6aafbd4bea741c3aef320",
          "body": "* build: pin Rust toolchain\n\n* build: verify PDFium archive checksums\n\n* ci: build and test CPSL on Linux\n\n* ci: build a CPSL macOS XCFramework slice\n\n* build: record CPSL artifact provenance\n\n* build: measure CPSL performance and CI reliability\n\n* build: scaffold a minimal Linux Bazel experiment\n\n*\n[…]\nl Rust builds for Apple\n\n* fix: always refresh CPSL Xcode outputs\n\n* build: verify downloaded PDFium archives\n\n* build: harden incremental CPSL Xcode builds\n\n* fix: support macOS sh in CPSL validation",
          "is_bot": false,
          "headline": "Harden CPSL builds with architecture-aware Xcode caching (#94)",
          "author_name": "Gaetan de Villele",
          "author_login": "gdevillele",
          "committed_at": "2026-07-15T23:32:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "689770e877b08fca1ce6a20776fcdbe990323e55",
          "body": null,
          "is_bot": false,
          "headline": "feat(apple): support pasted images and dropped attachments",
          "author_name": "dono",
          "author_login": "Donorhan",
          "committed_at": "2026-07-15T21:17:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9538bbdc42f7960eb5f667f9aafce2bc457d6aef",
          "body": null,
          "is_bot": false,
          "headline": "feat: conversation browsing v1 (#89)",
          "author_name": "Dono",
          "author_login": "Donorhan",
          "committed_at": "2026-07-15T20:52:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2518c5034c29a5cac2261544b702570a47af8c9d",
          "body": "* Polish Apple file, calendar, and attachment UX\n\n* Keep agent connectivity with iCloud mounts",
          "is_bot": false,
          "headline": "Polish Apple file, calendar, and attachment UX (#95)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-15T18:09:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c6fe5301e7849d732a98179c823a33c0276fb36b",
          "body": "* docs: rename grep CPSL module to ripgrep\n\n* Add CPSL iCloud mount session config support\n\n* Add read-only iCloud Drive mounts\n\n* Scope iCloud mounts to the iOS app\n\n* Fix iCloud mount isolation and staging\n\n* Fix iCloud mount isolation review findings\n\n* Make CPSL patch application deterministic\n\n\n[…]\nation\n\n* Persist mode-aware iCloud mounts\n\n* Mount original iCloud Drive folders\n\n* update cpsl submodule\n\n* Fix CPSL bootstrap headers for Xcode\n\n* Reorder iCloud mount setup flow\n\n* update submodule",
          "is_bot": false,
          "headline": "Add persistent iCloud Drive mounts with RO/RW access (#81)",
          "author_name": "Gaetan de Villele",
          "author_login": "gdevillele",
          "committed_at": "2026-07-14T23:48:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7f96348c949bbbecc5c347cfa2e1d7ef48e4a125",
          "body": null,
          "is_bot": false,
          "headline": "Track merged CPSL vision commit (#93)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-14T17:24:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "06b10f99e05db1c08dcd5bc1c9a1a6b2d23573a4",
          "body": "* update cpsl submodule\n\n* Fix Apple build warnings\n\n* Add configurable vision document reading\n\n* Update CPSL vision source-policy fix\n\n* Update CPSL vision module documentation\n\n* Satisfy Herm source policy checks",
          "is_bot": false,
          "headline": "Add configurable document vision to the CLI and Apple app (#92)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-14T04:50:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32325669b502f128abd81bf72113924801b12bbf",
          "body": "* update cpsl submodule\n\n* Improve chat interactions and activity feedback\n\n* Fix Swift warning cleanup\n\n* Fix remaining CPSL type isolation warnings\n\n* make glass more opaque\n\n* Polish chat links and Apple context controls\n\n* Refine calendar and location controls\n\n* Fix Apple context build warnings\n[…]\nerlay scrolling\n\n* Add attachments and harden agent browser workflows\n\n* Update CPSL webbrowser dependency\n\n* update cpsl submodule\n\n---------\n\nCo-authored-by: Gaetan de Villele <gdevillele@gmail.com>",
          "is_bot": false,
          "headline": "Polish the Apple agent experience and browser workflows (#90)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-12T18:56:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ffeaed81f0c2e328cfa48120abf5a507fab7407",
          "body": null,
          "is_bot": false,
          "headline": "Fix CPSL unsafe pointer handling (#86)",
          "author_name": "Gaetan de Villele",
          "author_login": "gdevillele",
          "committed_at": "2026-07-11T19:00:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "22655657360bd672f0f35b9f3a26176d59211de7",
          "body": "* update cpsl submodule\n\n* xproj changes\n\n* Add CPSL webbrowser integration to Herm\n\n* Exclude bundled skill files from Xcode resources\n\n* Remove stale CPSL composed mounts patch\n\n* Improve Herm webbrowser UI feedback\n\n* Make Herm webbrowser more Safari-like\n\n* Fix manual browser address submission\n\n* Clarify background browser usage\n\n* Update CPSL submodule\n\n* Share debug conversation JSON as file\n\n* Fix browser PDF trace issues\n\n* Update CPSL for iOS PDF build fix\n\n* Track merged CPSL main",
          "is_bot": false,
          "headline": "Add CPSL webbrowser integration (#85)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-08T21:06:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46889ef060dc8f074f805508348414eafcacaa14",
          "body": null,
          "is_bot": false,
          "headline": "Expand file preview support (#84)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-07T08:18:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b3e24ff9e15d314d9f64f03f80ab7ab8c3e1f848",
          "body": null,
          "is_bot": false,
          "headline": "Polish file browser navigation (#83)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-06T22:08:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acc3067b03cc3dbe924892d33ff7679870504133",
          "body": null,
          "is_bot": false,
          "headline": "Add voice dictation to the composer (#82)",
          "author_name": "Dono",
          "author_login": "Donorhan",
          "committed_at": "2026-07-06T22:01:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "209f1178c7e0cdb77a973a1caba2bf7e2c4269a5",
          "body": "* Add lazy agent skills support\n\n* Fix skills CI style violations\n\n* Refine beautiful PDFs skill guidance\n\n* Bundle Apple system skills\n\n* Improve Apple agent PDF harness\n\n* Add CLI skills listing command\n\n* Tighten CLI skills list display",
          "is_bot": false,
          "headline": "Add lazy agent skills support (#78)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-06T17:45:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c470f781406f5fcf15b5662f02baac58517fda48",
          "body": "Headless runs (herm -p) blocked for the full 60s init timeout and then\nprinted \"timed out waiting for initialization\" when no provider was\nconfigured, even though the missing provider is known much earlier. The\nwait loop only checked backend readiness, never the absence of a provider.\n\nwaitHeadlessR\n[…]\n predicate stays false while any async\ndiscovery path (model catalog, Apple runtime, Ollama, OpenRouter) is\nstill in flight, so valid keyless setups (Ollama, Apple runtime) and the\nTUI are unaffected.",
          "is_bot": false,
          "headline": "fix: fail fast in headless mode when no LLM provider is configured (#75)",
          "author_name": "Dono",
          "author_login": "Donorhan",
          "committed_at": "2026-07-06T17:44:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "28f76c6bb7f47fc7a67a6d4338b48da53b51ecc9",
          "body": "* Add shared helpers for target-aware CPSL XCFramework builds\n\nIntroduce scripts/lib/cpsl-xcframework.sh helpers to derive Apple Rust\ntargets from Xcode environment variables, validate XCFramework slices and\nPDFium sidecars, and add regression tests for the resolution logic.\n\n* Scope CPSL Apple arti\n[…]\nchor\nsource file.\n\n* Document configuration-aware CPSL Xcode auto-build\n\nUpdate CPSL_BUILD.md to describe target-selected builds, separate\nDebug/Release artifact paths, and the helper-target workflow.",
          "is_bot": false,
          "headline": "Make CPSL Xcode builds target and configuration aware (#79)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-07-05T16:52:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "49ed79d0a8d2d2555e3d2834a510d6e9bdb94747",
          "body": null,
          "is_bot": false,
          "headline": "Fix empty Apple env constants generation (#77)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-07-04T22:20:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "05c06f38397d0d9f4639615ef66a42d7ead8ec55",
          "body": null,
          "is_bot": false,
          "headline": "Update cpsl submodule (#76)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-07-04T22:13:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cdadba4fa829bdc3d20f1ddb87cafa8b628c3774",
          "body": null,
          "is_bot": false,
          "headline": "Update CPSL embedded FFI profile reference (#74)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-04T02:05:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2f6f69a764b73d446415416860d2651249113e53",
          "body": null,
          "is_bot": false,
          "headline": "Add Swift agent integration for Apple app (#73)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-07-03T02:01:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "56f117d2537e7b64d4d5fe38d16cdd391a0d5e89",
          "body": "* Add terminal macOS app launcher\n\n* Make Apple CPSL console terminal-like\n\n* Add iOS Apple dev script\n\n* remove debug screenshots\n\n* Fix macOS Apple build flow\n\n* Refine Apple chat UI and CPSL browsing\n\n* Fix iOS prompt composer behavior\n\n* Polish iOS chat integration\n\n* fix xcode warnings\n\n* Polis\n[…]\ntus stays clean without affecting the\ncommitted bootstrap stub files.\n\n* Polish Apple chat spacing\n\n* Make CPSL a tracked submodule\n\n---------\n\nCo-authored-by: Gaetan de Villele <gdevillele@gmail.com>",
          "is_bot": false,
          "headline": "Add Herm Apple chat UI with CPSL file browsing (#71)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-30T23:27:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "68852a8cd85bc20e3b5bc8523822c97a340f1491",
          "body": "Config files store API keys in plaintext. Writing with 0o644 makes them\nworld-readable. Changed to 0o600 so only the owner can read them.",
          "is_bot": false,
          "headline": "fix: restrict config file permissions to owner (0o600) (#72)",
          "author_name": "Lakshman Patel",
          "author_login": "Patel230",
          "committed_at": "2026-06-30T23:25:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a73e77bfd72c07a80a5b3c4e9ced8bea29dbfad7",
          "body": "* add Xcode project\n\n* build cpsl for iOS\n\n# Conflicts:\n#\t.gitignore\n\n* Add Apple CPSL XCFramework build script\n\n* Link CPSL XCFramework\n\n* Add CPSL debug REPL UI",
          "is_bot": false,
          "headline": "Add Apple CPSL debug app (#70)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-06-26T01:09:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0516a01dbf5a00ab8bee9d4328ed02e890dd4f6f",
          "body": "* Improve model display and config wrapping\n\n* Split config editor row rendering",
          "is_bot": false,
          "headline": "Improve model display and config wrapping (#69)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-25T23:58:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15821ed881c2eab5ab36c5f4b4f0da8c826b1a2e",
          "body": "* Add naked host sandbox mode\n\n* Refine naked permissions and approval UI\n\n* Fix macOS naked sandbox command startup\n\n* Broker macOS browser opens in naked mode\n\n* Fix macOS browser approvals UI\n\n* Loosen approval panel spacing\n\n* Center approval command detail\n\n* Preserve approval panel bottom edge\n\n* Satisfy CI checks for naked mode\n\n* Fix naked mode external access approvals\n\n* Satisfy naked approval CI checks",
          "is_bot": false,
          "headline": "Add naked host sandbox mode (#68)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-24T22:46:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9bbb6f85cb40fa67abb8284cba711b5ab8f873a6",
          "body": "…(#55)\n\n* Fix model display and config editor behavior when no API keys are configured\n\nSuppress the confusing \"model is unknown; no fallback model is available\"\ndiagnostic warning when no deployments are configured. Hide model values\nin the project config editor tab when no providers are set, showi\n[…]\ning Deployments clone. Adds a regression\ntest that fails without the clone (edit leaks into globalConfig.Routing)\nand passes with it.\n\nAddresses the config-draft aliasing issue noted in PR #55 review.",
          "is_bot": false,
          "headline": "Require explicit model selection and fix config UX with no providers …",
          "author_name": "Lakshman Patel",
          "author_login": "Patel230",
          "committed_at": "2026-06-24T17:44:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f4fc463baca3da3e995105699a64de06bb26c346",
          "body": "* update langdag submodulel\n\n* Improve TUI message and code rendering\n\n* Tune TUI color roles",
          "is_bot": false,
          "headline": "Improve TUI message and code rendering (#64)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-23T17:38:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67726e379cc7775d3f1e69f24fc9f0a066611afe",
          "body": "* Move vet file selection into config\n\n* Pin vet to merged file selection commit",
          "is_bot": false,
          "headline": "Move vet source selection into config (#67)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-06-23T16:40:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a7b0c2c51a1e11039c58f4bf68eae1012a545381",
          "body": null,
          "is_bot": false,
          "headline": "Check Swift files with vet in pre-commit (#66)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-06-23T02:06:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca0dfff8c58ef30bfd381b131c16367c1a98dd84",
          "body": "* Replace pre-commit checks with vet\n\n* Update vet config schema",
          "is_bot": false,
          "headline": "Replace pre-commit checks with vet (#65)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-06-23T01:56:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac3ad7efbdccdfbd63e24d1e88e675f9d1032c0d",
          "body": "* cli: add cpsl backend flags\n\n* cpsl: add worker process and protocol\n\n* cpsl: route bash through CPSL\n\n* cpsl: pass network policy to worker\n\n* test: add cpsl smoke path\n\n* cpsl: polish CPSL demo mode\n\n* cpsl: clarify sandbox shell discovery\n\n* cpsl: prefer native Luau execution\n\n* cpsl: default a\n[…]\n* cpsl: gate web search by network policy\n\n* cpsl: pin merged http policy build\n\n* test: keep remote catalog fixture fresh\n\n* ci: check prompt lengths recursively\n\n* cpsl: satisfy structural ci checks",
          "is_bot": false,
          "headline": "Add CPSL dynamic-library sandbox backend (#62)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-19T18:28:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba81e83e93e591359b4b605069e145735dce03d9",
          "body": "* Add Apple Foundation Models support\n\n* Update langdag Apple tool schema handling\n\n* Track merged langdag Apple support",
          "is_bot": false,
          "headline": "Add Apple Foundation Models support (#63)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-10T00:21:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2dbba5c933c4752321c51e135c29297b99b950c7",
          "body": null,
          "is_bot": false,
          "headline": "Update langdag to v0.9.0 (#61)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-06-03T21:49:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8e8d2e46b7ba690907230da81d9a2dcabc19241a",
          "body": "Co-authored-by: herm <herm@hermagent.com>",
          "is_bot": false,
          "headline": "persist fetched model catalog to disk cache for next launch (#60)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-05-29T16:31:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb1df8a5f1c06eeabb32d11e05aa179809598df6",
          "body": "Co-authored-by: herm <herm@hermagent.com>",
          "is_bot": false,
          "headline": "add Ctrl+L to clear conversation, allow /clear while agent runs (#59)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-05-29T16:30:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "efb55947c01d503c20455ffb98395e7918188104",
          "body": "* Retry Docker check when not available at startup\n\nInstead of showing a permanent error when Docker is not running,\nretry every 3 seconds until it becomes available. The status bar\nshows the error state (red) while retrying; no chat message is\nadded since the retry is automatic. Uses the app's stopCh for\nclean shutdown.\n\n* Keep Docker retry error visible\n\n---------\n\nCo-authored-by: aduermael <adrien@duermael.com>",
          "is_bot": false,
          "headline": "Retry Docker check when not available at startup (#7)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-05-26T18:15:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00c1a17e62dc2ab293d894cb9726d35f649df47d",
          "body": null,
          "is_bot": false,
          "headline": "(docs) Update source install docs for langdag submodule (#54)",
          "author_name": "Lee Samuel",
          "author_login": "LeeSamuel14",
          "committed_at": "2026-05-26T17:30:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "baa37ba9363acc066b85bdb3c7aa0e4e5b11c756",
          "body": "…#53)\n\n* Improve secret key display and Delete key behavior in config editor\n\nmaskKey now always shows start/end chars for all key lengths instead\nof showing \"****\" for short keys. Secret fields show password-style\nasterisks with start/end visible in edit mode. Delete/Backspace\nclears the entire edi\n[…]\n\nbackward) now clear the entire edit buffer when editing a secret field,\nmatching the existing Backspace and Delete behavior. Adds tests for all\nthree shortcuts and a TestSecretEditDisplay table test.",
          "is_bot": false,
          "headline": "Improve secret key display and Delete key behavior in config editor (…",
          "author_name": "Lakshman Patel",
          "author_login": "Patel230",
          "committed_at": "2026-05-26T17:02:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "02a71fc507a31198c171fee9873e5d430336bd04",
          "body": "* Remove unnecessary base URL fields from config editor\n\nOpenAI Base URL, Grok Base URL, and OpenRouter Base URL were shown\ncontextually in the Deployments tab but aren't useful — base URLs are\nbaked into deployments. Ollama Base URL is kept as it's the only one\nusers actually configure.\n\n* Update tests to match removed base URL fields",
          "is_bot": false,
          "headline": "Remove unnecessary base URL fields from config editor (#52)",
          "author_name": "Lakshman Patel",
          "author_login": "Patel230",
          "committed_at": "2026-05-26T17:01:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "486f89c37a750bcdb8bf3163efbda0fa228420af",
          "body": null,
          "is_bot": false,
          "headline": "Fix input redraw when scroll window changes (#51)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-05-26T16:59:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dec06deefa2b09bfe60ac438a2ebabc73a5dccce",
          "body": "* Fix Ghostty shifted key input\n\n* Handle encoded Shift Enter",
          "is_bot": false,
          "headline": "Fix Ghostty shifted key input (#50)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-05-22T21:58:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f4d3f31c7b4a6e609f523c67544b8848b04231c4",
          "body": null,
          "is_bot": false,
          "headline": "Improve Herm cancellation and prompt harness (#49)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-05-21T18:01:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e920a219982e3675f6e3d9d7f5111ce7a913d58c",
          "body": "* Add deployment-aware model catalog plan\n\n* Capture deployment routing decisions in plan\n\n* Clarify cost accounting source in deployment plan\n\n* Ignore local agent skills directory\n\n* Clarify deployment-aware model catalog plan\n\n* 0: Lock deployment catalog phase 0\n\n* plan update\n\n* 1: Define deplo\n[…]\nerged main\n\n* Polish deployment-aware UI and tests\n\n* track LangDAG OpenAI protocol support\n\n* Improve CLI inline block layout\n\n* Add headless prompt cache and continuation\n\n* Update langdag submodule",
          "is_bot": false,
          "headline": "Add deployment-aware model catalog and routing (#47)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-05-20T23:14:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ee0eec4be9dd623ba2c5850e20e4eb50dbe5f4b",
          "body": "* feat: add OpenRouter provider support\n\n- Add ProviderOpenRouter constant and dynamic model fetching via\n  fetchOpenRouterModels / fetchOpenRouterModelsFrom (testable with httptest)\n- Wire up in agent.go priority chain (after grok, before gemini),\n  config.go (defaultActiveModels, defaultExploratio\n[…]\nrom to satisfy the\nmax-1-positional-param rule, and trim main.go to exactly 1000 lines.\n\n* ci: re-trigger tests (flaky TempDir cleanup)\n\n* style: add parameter bundle comment to fetchOpenRouterOptions",
          "is_bot": false,
          "headline": "feat: add OpenRouter provider support (#19)",
          "author_name": "Lakshman Patel",
          "author_login": "Patel230",
          "committed_at": "2026-05-02T22:28:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fbe7c48139249d0666eb28ddbd43168987b9c838",
          "body": "Co-authored-by: herm <herm@hermagent.com>",
          "is_bot": false,
          "headline": "fix expired Discord invite link (#43)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-28T02:00:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe016b04821e1501f982af8fb4a2945d368e8e4c",
          "body": "* Add claude-opus-4-7 to test fixtures\n\n* Keep claude-opus-4-6 in catalog test fixtures alongside 4-7\n\nMake modelsFromCatalog test fixtures additive to match the convention\nused in defaultTestModels (config_test.go), instead of replacing 4-6\nwith 4-7.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>\n\n* update langdag submodule\n\n---------\n\nCo-authored-by: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add claude-opus-4-7 to model test fixtures (#28)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-27T23:21:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8b929100dd56b1b4ea6cf8ab7f5078a64fed5a0c",
          "body": "Fixes the v2.6 deprecation warning in the release workflow.",
          "is_bot": false,
          "headline": "Migrate goreleaser archives.format to formats list (#27)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-26T06:23:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ddc82376fa9c7add7321ce83e639314bfeb40fad",
          "body": "On the Project tab, pressing Backspace on a field clears the project\noverride so the value falls back to the global setting. The help line\nshows the new keybind only on this tab.\n\nCo-authored-by: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Allow Backspace to unset project-level config fields (#37)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-26T06:22:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bbe776b7c6b957a7b392ada807d0b883dc919f38",
          "body": "Co-authored-by: herm <herm@hermagent.com>",
          "is_bot": false,
          "headline": "grey out global model hint in project tab when unselected (#41)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-26T06:21:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "028666b059fbbad4202f1f18b0d542c13b9d08e2",
          "body": "Each call to render() and renderInput() now brackets its output buffer\nwith begin/end synchronized update sequences (\\033[?2026h / \\033[?2026l).\nSupporting terminals commit the frame atomically instead of streaming\nbytes incrementally, so the cursor no longer visibly walks through\nintermediate row positions during ticker-driven repaints. Terminals\nthat don't recognize the sequence ignore it harmlessly.\n\nCo-authored-by: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Wrap render frames in DEC mode 2026 to eliminate cursor flicker (#42)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-26T06:20:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1d93626ded1644d8761fc8dca956c1f5fc94b782",
          "body": "* Bump langdag submodule to pick up GPT-5.5 catalog entries\n\nBumps external/langdag to include gpt-5.5-2026-04-23 and\ngpt-5.5-pro-2026-04-23 in the embedded model catalog so herm can compute\ncost and capability for the new OpenAI models.\n\nDepends on fundamental-research-labs/langdag#14.\n\nCo-Authored\n[…]\nental-research-labs/langdag#14) now that the GPT-5.5 catalog PR\nhas landed.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add GPT-5.5 support (submodule bump) (#35)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-24T23:21:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "296d95fa1c04760455945fbbe0cc36992d0b7b7e",
          "body": "Replace the outdated OCI/Windows roadmap with the five items we're actually planning to work on, ordered by rough priority.",
          "is_bot": false,
          "headline": "Refresh roadmap with current priorities (#34)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-24T23:18:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1858bab3fb28cd46ff5f5dadf98d5532a2b44e57",
          "body": "…ocstrings) (#32)\n\n* Plan: CI code-quality checks (file length, positional params, docstring)\n\n* Plan: resolve open questions for CI code-quality checks\n\n* 1a: Scaffold tools/ci-check with subcommand dispatch\n\nStdlib-only Go program. Adds go.mod, main.go dispatch, shared walker\nwith exclusion set, A\n[…]\nes (file\nlength, docstrings, positional-params) are not meant to govern\nthird-party code checked in under external/. Walk now skips any\ndirectory named external, same treatment as vendor/node_modules.",
          "is_bot": false,
          "headline": "Add CI-enforced code-quality rules (file length, positional params, d…",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-23T17:56:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "741132e7bec9cac5039bc339c1dc13189a87b493",
          "body": "* Track langdag as submodule at external/langdag\n\nReplaces the optional external-deps-workspace/ clone (and its\nuse-local-dep.sh bootstrapper) with a tracked git submodule. go.work is\nnow committed so every build resolves langdag through the submodule.\n\n* CI: fetch submodules in checkout step\n\ngo.work now references external/langdag; without submodules the Go\ntoolchain can't resolve it.",
          "is_bot": false,
          "headline": "Track langdag as submodule at external/langdag (#33)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-23T16:22:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8aba481bbe6abda21b5e797eb71413ba4f6c933f",
          "body": "* delegate connection-level retry to langdag, remove herm's duplicate retry logic\n\nherm had its own retryablePrompt loop that duplicated langdag's internal\nretryProvider, causing up to N×M total attempts on transient errors.\nThis removes herm's connection-level retry (retryablePrompt, isRetryableErr\n[…]\nleased.\nSet RetryConfig.BaseDelay to 2s to match the previous herm default.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Delegate retry to langdag, remove duplicate retry logic (#22)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-15T19:07:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6bba40db7696ed5ab711ea40889db120b982fcee",
          "body": "* Add plan: sub-agent system refactor (modes, DRY, communication, budget)\n\n7-phase plan covering mode rename (implement→general), drain loop\ndeduplication, per-mode turn budgets, output summarization tuning,\nsnapshot caching, budget reminder streamlining, and compact improvements.\n\n* 1a: Add ModeExp\n[…]\n to misorder). Delete zombie defaultSubAgentMaxTurns constant\n(replaced by defaultGeneralMaxTurns everywhere). Fix stale \"~500 bytes\"\ncomment on summarizeOutput. Move completed plan to plans/archive/.",
          "is_bot": false,
          "headline": "Refactor sub-agent system: modes, DRY, efficiency (#26)",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-15T18:42:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8a5417944c6457af9ed64fa2fdece73fefe74d84",
          "body": "* update github workflows to use latest actions versions\n\nCo-authored-by: herm <herm@hermagent.com>\n\n* use checkout v5 and keep upload-pages-artifact at v4\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: herm <herm@hermagent.com>\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Update GitHub workflow actions to latest versions (#21)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-12T18:18:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a18d67b047467f5e5ea349e241d66f8e95ade6c5",
          "body": "* update branch name in periodic commit info refresh\n\nCo-authored-by: herm <herm@hermagent.com>\n\n* remove trailing whitespace in fetchCommitInfo\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: herm <herm@hermagent.com>\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Refresh branch name in periodic commit info (#24)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-12T18:10:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2580df1996ed47c8d024f283688fe8e2dced94ab",
          "body": "Unify Gemma and Gemini providers",
          "is_bot": false,
          "headline": "Merge pull request #25 from aduermael/gdevillele/check",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-12T18:05:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae3a26a2a72783c29b4b38d04a6bc4dd0d6de855",
          "body": "Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "bump langdag to v0.8.2 (fix Gemini streaming stop reason)",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-12T17:54:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "12997798851eaf1c4214a56a6a4b0b5d375bdd5d",
          "body": "langdag merged Gemma into Gemini — both use the same Google AI Studio\nAPI and API key. Remove the separate Gemma provider from herm; Gemma\nmodels now appear under the Gemini provider.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "unify Gemma and Gemini providers to match langdag upstream",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-12T17:19:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a237eceb4c0f4d307c7fd8ed3440f4eb7bd6ee92",
          "body": "add Gemma provider support",
          "is_bot": false,
          "headline": "Merge pull request #20 from aduermael/add-gemma-4-support",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-11T05:08:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f763eda2b7629b3f52cde971be69a52d85531975",
          "body": "Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "bump langdag to v0.8.1 and remove local replace",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-11T03:49:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "19a124023e6c1572e88727f443a1b471b30ad4d0",
          "body": "Point go.mod replace at ./external-deps-workspace/langdag so the fixed\nGemma model IDs are picked up before a langdag release is tagged.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "use local langdag replace for development",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-10T09:18:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "35fca9a7ec20086c3b0b42faa7456a0a294c6b39",
          "body": "Update default active model to gemma-4-31b-it and exploration model to\ngemma-3-4b-it to match the corrected langdag catalog entries.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix Gemma default model IDs to match API identifiers",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-10T09:11:21Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "71d4091f2a2982cf4ff25d1b5e0109ec54896a55",
          "body": "Add ProviderGemma constant, GemmaAPIKey config field, and a Gemma row\nin the API keys config tab. Wire Gemma into newLangdagClient and the\nprovider-specific client factory. Defaults: gemma-4 as active model\nand gemma-3-4b as exploration model.\n\nRequires the matching add-gemma-4-support branch in langdag.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "add Gemma provider support",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-10T07:56:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "649c08c4d8f9e5f101c3eb6654b4029f2299f9a3",
          "body": "Config UX: effective provider visibility, stable tab focus, and newline-safe streaming",
          "is_bot": false,
          "headline": "Merge pull request #17 from Patel230/fix/config-effective-provider-focus",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-08T23:18:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5b53d3bdf5931e65263fb73b2f277c02c5dc226f",
          "body": "Co-authored-by: herm <herm@hermagent.com>",
          "is_bot": false,
          "headline": "add X/Twitter link (@herm_agent) to website",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-08T17:24:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2b7df39aedb6626e4b99f2fdc4197f607d294ff9",
          "body": null,
          "is_bot": false,
          "headline": "Fix project config row rendering for model hints/overrides",
          "author_name": "Patel230",
          "author_login": "Patel230",
          "committed_at": "2026-04-07T18:26:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b4980ce85dfee360845c0f4463b0f30b3e50a65",
          "body": "fix: clean up buildx builder container after image build",
          "is_bot": false,
          "headline": "Merge pull request #18 from aduermael/gdevillele/fix-docker-build",
          "author_name": "Adrian Duermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-07T17:08:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c04121009ffffb28aa3e5fdd10f0b67540f0c59a",
          "body": null,
          "is_bot": false,
          "headline": "fix: clean up buildx builder container after image build",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-07T00:39:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5cd1f81f9926c96c6f5390b3fdcf7764d2a6c368",
          "body": null,
          "is_bot": false,
          "headline": "tests: make effective-provider config coverage provider-agnostic",
          "author_name": "Patel230",
          "author_login": "Patel230",
          "committed_at": "2026-04-06T21:26:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "abcf1b20984c0b372d22b928e13d252b86c34213",
          "body": null,
          "is_bot": false,
          "headline": "config ui: show effective provider, preserve tab focus, and add coverage",
          "author_name": "Patel230",
          "author_login": "Patel230",
          "committed_at": "2026-04-06T21:16:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "76edce7a4ce83b5e02a549a2279068c4bd695e20",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'aduermael:main' into main",
          "author_name": "Lakshman Patel",
          "author_login": "Patel230",
          "committed_at": "2026-04-06T17:32:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1970b188f6b5afba53666a737e2fa2170847d152",
          "body": "fix: prevent duplicate Ollama offline warning on startup",
          "is_bot": false,
          "headline": "Merge pull request #16 from Patel230/fix/ollama-duplicate-warning",
          "author_name": "Gaëtan de Villèle",
          "author_login": "gdevillele",
          "committed_at": "2026-04-06T17:21:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "31028d9e39a5dfe3ad420fc62cd36548377075f7",
          "body": null,
          "is_bot": false,
          "headline": "ci: increase source file line limit from 1500 to 1750",
          "author_name": "Patel230",
          "author_login": "Patel230",
          "committed_at": "2026-04-06T17:01:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d786c76ff318f61c64508580818961dd8382b83d",
          "body": null,
          "is_bot": false,
          "headline": "ci: increase source file line limit from 1500 to 1750",
          "author_name": "Patel230",
          "author_login": "Patel230",
          "committed_at": "2026-04-06T16:49:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bdac6161796399cf98c8e78d5e0f24e2592dd09a",
          "body": null,
          "is_bot": false,
          "headline": "fix: prevent duplicate Ollama offline warning on startup",
          "author_name": "Patel230",
          "author_login": "Patel230",
          "committed_at": "2026-04-06T14:29:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4cea6273eb05042a5f7122228ab330517b4705c5",
          "body": null,
          "is_bot": false,
          "headline": "update langdag version",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T19:40:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "39f94d170e67c2710acd34422499ac0149fab46f",
          "body": "The Anthropic API requires tool_result blocks to appear before other\ncontent in the user message following tool_use. Prepending the\n<system-reminder> text block broke this pairing, causing 400 errors.",
          "is_bot": false,
          "headline": "fix: append budget reminder after tool_results, not before",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T17:22:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2572a61391871d8b0a88afd9e82f69770d24351",
          "body": "…vior, update plan",
          "is_bot": false,
          "headline": "8a-8c: delete systemPromptWithStats(), document WithSystemPrompt beha…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T16:59:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f8d9fba60859aa9c73fbea72aeb91ad3ef37a21",
          "body": "…mpt caching\n\nbudgetReminderBlock() generates <system-reminder> text blocks prepended to\ntool results on follow-up LLM calls. systemPromptWithStats() now returns the\nstatic prompt unchanged, keeping it identical across turns for cache hits.",
          "is_bot": false,
          "headline": "7a-7g: move dynamic stats from system prompt to user messages for pro…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T07:54:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "deb7dc0716cd6e35f802751fc14a4b79f67285b4",
          "body": "… caching\n\nPhase 7 moves per-turn budget/stats content from the system prompt into\n<system-reminder> user message blocks. The system prompt becomes fully\nstatic and cacheable. Phase 8 cleans up dead code from the old approach.",
          "is_bot": false,
          "headline": "plan: add phases 7-8 — move dynamic stats to user messages for prompt…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T07:39:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e1556f6bf0b595be08b605fb469a8e3d7ec7a48d",
          "body": "Tests verify: full lifecycle with tool calls and text synthesis (6a),\nforced synthesis when budget is exceeded (6b), background agent events\nand budget injection (6c), and system prompt/tool description budget\ncontent (6d).",
          "is_bot": false,
          "headline": "6a-6d: add integration tests for budget-aware sub-agent lifecycle",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T06:28:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0f42f325d7bb01bd93696646108ee5e4fc5f758",
          "body": "… residual literals",
          "is_bot": false,
          "headline": "5e: add test verifying budget constants flow into all outputs with no…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:57:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34db7936e05fa4fd533f3e4dcb99086456f66949",
          "body": "…t magic numbers",
          "is_bot": false,
          "headline": "5d: make budget tests dynamic — derive turn values from constants, no…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:55:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "86bd2966ed3e6740cb6314b68e27d589938a93b3",
          "body": "…ntMaxTurns",
          "is_bot": false,
          "headline": "5c: replace hardcoded fallback 15 in config editor with defaultSubAge…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:54:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd482a760b9d1f7f5ecf4de60f293d04359849b0",
          "body": "…aceholder",
          "is_bot": false,
          "headline": "5b: replace hardcoded turns in agent.md with __DEFAULT_MAX_TURNS__ pl…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:53:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9df86a41b9b32aade83942fa1f4c33bd1873101",
          "body": null,
          "is_bot": false,
          "headline": "5a: flow DefaultSubAgentMaxTurns into prompt templates via PromptData",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:53:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3bc819bbd234ce0ab9a6a8d306acb8a49acd952b",
          "body": "…ed warnings\n\nAdd context window utilization and session cost to systemPromptWithStats().\nReplace single 30% iteration warning with graduated thresholds at 50%/25%.\nWire SetSessionCost from TUI to agent for budget-aware system prompts.",
          "is_bot": false,
          "headline": "4a-4d: main agent budget visibility — context window %, cost, graduat…",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:46:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3db595139d573ead7446668439fb5886a158ef8c",
          "body": null,
          "is_bot": false,
          "headline": "plan: add phase 5 to centralize budget constants, renumber phases",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:37:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f10fd4fde849ca55adc2813d3bfd94e2542a0c90",
          "body": "Sub-agent role prompt gets a Budget Management section teaching turn\npacing. Agent tool description and main agent role prompt now mention\nthe 20-turn default so tasks get scoped appropriately. Five new tests\nverify the prompt sections appear in built system prompts.",
          "is_bot": false,
          "headline": "3a-3d: add budget management guidance to prompts and tests",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:34:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "003033be0504bcee39772dbbbc43e80040b98c63",
          "body": "Two-stage turn enforcement: at maxTurns+1, cancel and make a\ntools-disabled synthesis call instead of instant hard kill. Adds\ngracefulSubAgentSynthesis, updates both Execute and runBackground\ndrain loops with unified post-loop synthesis, and tracks lastNodeID\nfor reliable synthesis after context cancellation.",
          "is_bot": false,
          "headline": "2a-2e: soft wrap-up before hard kill for sub-agents",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T05:31:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fff7e9a005df6b5e909f35899294c658d566f529",
          "body": "Add turnBudget fields (maxTurns, turnsUsed, turnTokensIn/Out) to Agent\nwith thread-safe SetTurnProgress/SetTokenProgress methods. Extend\nsystemPromptWithStats() with tiered budget messages at 50/75/90%\nthresholds. Wire up drain loops in Execute() and runBackground().",
          "is_bot": false,
          "headline": "1a-1e: inject turn budget progress into sub-agent system prompts",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T01:58:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f5dc0a05903ea80f2765e6af25ff59bcf82ef4f",
          "body": null,
          "is_bot": false,
          "headline": "plan: agent budget consciousness for turns, tokens, and self-regulation",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T01:49:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3efccb0c564922c21c1a522cb638371869a64735",
          "body": "After Run() returns, defer close(a.events) closes the event channel\nwhile background sub-agent goroutines may still be running (when\nbackgroundCompletion() timed out). The sub-agent's \"done\" event send\npanics on the closed channel, is silently recovered, and the TUI never\nlearns the sub-agent finish\n[…]\nGroup) before\n  closing the event channel, giving them time to forward final events\n- Defensive: force-complete active sub-agents in the TUI when the\n  event channel closes, so the UI never gets stuck",
          "is_bot": false,
          "headline": "fix sub-agent spinner stuck forever when event channel closes early",
          "author_name": "aduermael",
          "author_login": "aduermael",
          "committed_at": "2026-04-04T01:25:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 16,
      "commits_last_year": 956,
      "latest_release_at": "2026-07-17T19:54:15Z",
      "latest_release_tag": "v0.8.7",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 19,
      "days_since_latest_release": 4,
      "mean_days_between_releases": 10.1
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 9,
      "stars": 218,
      "watchers": 5,
      "fork_history": {
        "days": [
          {
            "date": "2026-03-16",
            "count": 3
          },
          {
            "date": "2026-03-19",
            "count": 1
          },
          {
            "date": "2026-03-20",
            "count": 2
          },
          {
            "date": "2026-05-26",
            "count": 1
          },
          {
            "date": "2026-06-21",
            "count": 1
          },
          {
            "date": "2026-07-04",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 9,
        "total_forks": 9
      },
      "star_history": null,
      "open_issues_and_prs": 19
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod",
        "tools/ci-check/go.mod",
        "tools/edit-file/go.mod",
        "tools/outline/go.mod",
        "tools/write-file/go.mod"
      ],
      "largest_source_bytes": 182845,
      "source_files_sampled": 241,
      "oversized_source_files": 8,
      "agent_instruction_files": [
        "prompts/container/tools/agent.md",
        "prompts/cpsl/tools/agent.md",
        "prompts/naked/tools/agent.md"
      ],
      "agent_instruction_max_bytes": 3302
    },
    "dependencies": {
      "manifests": [
        "go.mod"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "go"
      ],
      "dependencies": [
        {
          "name": "github.com/ebitengine/purego",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.10.1"
        },
        {
          "name": "github.com/google/uuid",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.0"
        },
        {
          "name": "github.com/rivo/uniseg",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.4.7"
        },
        {
          "name": "golang.org/x/term",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.40.0"
        },
        {
          "name": "gopkg.in/yaml.v3",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v3.0.1"
        },
        {
          "name": "langdag.com/langdag",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.10.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": 4,
        "merged_prs": 75,
        "open_issues": 15,
        "closed_ratio": 0,
        "closed_issues": 0,
        "closed_unmerged_prs": 8
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "aduermael",
          "commits": 874,
          "avatar_url": "https://avatars.githubusercontent.com/u/6775074?v=4"
        },
        {
          "type": "User",
          "login": "gdevillele",
          "commits": 61,
          "avatar_url": "https://avatars.githubusercontent.com/u/939999?v=4"
        },
        {
          "type": "User",
          "login": "Patel230",
          "commits": 16,
          "avatar_url": "https://avatars.githubusercontent.com/u/17196758?v=4"
        },
        {
          "type": "User",
          "login": "Donorhan",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/3781087?v=4"
        },
        {
          "type": "User",
          "login": "LeeSamuel14",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/37692342?v=4"
        }
      ],
      "contributors_sampled": 5,
      "top_contributor_share": 0.914
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci-checks.yml",
        "pages.yml",
        "prompt-length.yml",
        "release.yml",
        "test.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "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": 4,
            "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": "30 out of 30 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": 10,
            "reason": "all changesets reviewed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 4 contributing companies or organizations",
            "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": 0,
            "reason": "no 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 7 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": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "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": "32 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "f2da284547f6137553f8a84ab4ebd63069ff3287",
        "ran_at": "2026-07-22T11:08:31Z",
        "aggregate_score": 4.6,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-19T01:16:54Z",
      "oldest_open_prs": [
        {
          "number": 58,
          "created_at": "2026-05-29T07:57:59Z",
          "last_comment_at": "2026-07-17T04:16:21Z",
          "last_comment_author": "LeeSamuel14"
        },
        {
          "number": 91,
          "created_at": "2026-07-12T19:55:05Z",
          "last_comment_at": "2026-07-14T17:31:55Z",
          "last_comment_author": "aduermael"
        },
        {
          "number": 101,
          "created_at": "2026-07-19T21:33:02Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 102,
          "created_at": "2026-07-21T18:14:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-19T01:16:29Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 2,
          "created_at": "2026-03-21T17:36:39Z",
          "last_comment_at": "2026-05-14T09:30:10Z",
          "last_comment_author": "Patel230"
        },
        {
          "number": 8,
          "created_at": "2026-03-27T16:32:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 11,
          "created_at": "2026-03-30T04:59:27Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 23,
          "created_at": "2026-04-11T17:08:31Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 29,
          "created_at": "2026-04-20T19:30:14Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 30,
          "created_at": "2026-04-21T16:01:52Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 31,
          "created_at": "2026-04-22T18:39:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 38,
          "created_at": "2026-04-25T03:45:04Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 39,
          "created_at": "2026-04-25T03:45:30Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 45,
          "created_at": "2026-05-10T08:57:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 48,
          "created_at": "2026-05-20T22:31:00Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 56,
          "created_at": "2026-05-28T21:36:42Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 57,
          "created_at": "2026-05-28T21:36:57Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 87,
          "created_at": "2026-07-11T21:54:44Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 88,
          "created_at": "2026-07-11T22:41:00Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/aduermael/herm",
    "host": "github.com",
    "name": "herm",
    "owner": "aduermael"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 61,
      "inputs": {
        "security": 46,
        "vitality": 82,
        "community": 49,
        "governance": 46,
        "engineering": 81
      },
      "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": 77,
            "inputs": {
              "commits_last_year": 956,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 19
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "19/52 weeks with commits",
                "points": 13.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 19
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "956 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 956
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 7 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": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 16,
              "latest_release_tag": "v0.8.7",
              "releases_from_tags": false,
              "days_since_latest_release": 4,
              "mean_days_between_releases": 10.1
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "16 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 16
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~10.1 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 10.1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "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": 49,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "at_risk",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 49,
            "inputs": {
              "forks": 9,
              "stars": 218,
              "watchers": 5,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "218 stars",
                "points": 37.9,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 218
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "9 forks",
                "points": 7.5,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "5 watchers",
                "points": 3.3,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 46,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 28,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 5,
              "top_contributor_share": 0.914
            },
            "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 91% of commits",
                "points": 1.9,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 91
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "5 contributors",
                "points": 6.8,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 4 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "merged_prs": 75,
              "open_issues": 15,
              "closed_issues": 0,
              "issue_closed_ratio": 0,
              "closed_unmerged_prs": 8
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "0% of issues closed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 0
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "75/83 decided PRs merged",
                "points": 34.6,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 75,
                      "decided": 83
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "all changesets reviewed",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 63,
            "inputs": {
              "followers": 143,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "aduermael",
              "public_repos": 75,
              "account_age_days": 4530
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "143 followers of aduermael",
                "points": 15.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 143,
                      "login": "aduermael"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "75 public repos, account ~12 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 75
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 12
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 81,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "30 out of 30 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": 100,
            "inputs": {
              "topics": [
                "ai",
                "ai-agents",
                "coding-agent",
                "containerization",
                "sandbox",
                "terminal"
              ],
              "has_wiki": true,
              "homepage": "https://hermagent.com",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://hermagent.com",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "6 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "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": "at_risk",
        "name": "Security",
        "value": 46,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 46,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 4.6
            },
            "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,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "30 out of 30 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": "all changesets reviewed",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 4 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "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": "no update tool detected",
                "points": 0,
                "status": "missed",
                "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 7 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 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "32 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 5
            },
            "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": "good",
        "name": "AI Readiness",
        "value": 78,
        "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": 0.87,
              "agent_instruction_files": [
                "prompts/container/tools/agent.md",
                "prompts/cpsl/tools/agent.md",
                "prompts/naked/tools/agent.md"
              ],
              "agent_instruction_max_bytes": 3302
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "prompts/container/tools/agent.md, prompts/cpsl/tools/agent.md, prompts/naked/tools/agent.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "prompts/container/tools/agent.md, prompts/cpsl/tools/agent.md, prompts/naked/tools/agent.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": "87 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 87,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 66,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.13,
              "toolchain_manifests": [
                "go.mod",
                "tools/ci-check/go.mod",
                "tools/edit-file/go.mod",
                "tools/outline/go.mod",
                "tools/write-file/go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "go.mod, tools/ci-check/go.mod, tools/edit-file/go.mod (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "go.mod, tools/ci-check/go.mod, tools/edit-file/go.mod"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "13 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 13,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 98,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 182845,
              "source_files_sampled": 241,
              "oversized_source_files": 8
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "8/241 source files over 60KB",
                "points": 53.2,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 241,
                      "oversized": 8
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "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-22T11:08:52.638337Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/aduermael/herm.svg",
  "full_name": "aduermael/herm",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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