Публічний реєстр
Звіт про здоров'я програмного забезпеченнясхема 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 р.Переглянути на GitHub ↗

aduermael/herm має індекс здоров’я 61 зі 100, що відповідає смузі «Помірний». Найвищий показник — Vitality (82/100), найнижчий — Security (46/100). Останнє оновлення — сьогодні. Більшість нещодавньої роботи виконує один учасник.

61
загалом / 100
Помірний

Індекс здоров'я програмного забезпечення

Метрики згруповано у зважені категорії на шкалі 1–100. Загальна оцінка починається як їхнє середнє; коли публічні дані активують Політику юрисдикцій високого ризику, рейтинг коригується й отримує верхню межу 49 («Під ризиком»). Готовність до ШІ не входить до індексу.

61
Відмінний85-100Зразковий; відповідає практично всім перевіреним критеріям
Добрий70-84Здоровий; незначні прогалини
Помірний50-69Прийнятний, але з помітними прогалинами; рекомендовано перевірку
У зоні ризику30-49Суттєві слабкі місця; впровадження потребує обережності
Критичний1-29Серйозні проблеми (покинутий, єдиний мейнтейнер, без базової гігієни)
ЖиттєздатністьСпільнота тавпровадженняСталість таврядуванняІнженернаякістьБезпекаГотовність доШІ

Профіль оцінок

Кожна вісь — окрема категорія. Форма важить більше, ніж середнє: здоровий об'єкт заповнює всю фігуру, тоді як профіль із піками та провалами означає, що сила в одному вимірі маскує ризик в іншому.

Власність

Adrian DuermaelОсобистий обліковий запис
143 підписники75 публічних репозиторіївз лют. 2014 р.shortcut.ai

Цей репозиторій належить особистому обліковому запису. Проєкт з єдиним власником несе більший ризик безперервності, ніж підтримуваний організацією.

Метрики за категоріями

Життєздатність

Чи живий проєкт — чи пишеться код і чи виходять релізи?

82Добрий · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 0 дн. тому
13.2/36Ритм комітів — 19/52 тижнів із комітами
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
Як обчислюється оцінка
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% загального індексу
Як обчислюється оцінка
37.9/60Зірки — 218 зірок
7.5/25Форки — 9 форків
3.3/15Спостерігачі — 5 спостерігачів
Використані вхідні дані
forks9
stars218
watchers5
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
0/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
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Вирішення issue — закрито 0% issue
34.6/38.3Прийняття PR — злито 75/83 вирішених PR
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Охоплення власника — 143 підписників у aduermael
25/25Послужний список — 75 публічних репозиторіїв, вік облікового запису ~12 р.
Використані вхідні дані
followers143
owner_typeUser
is_verified
owner_loginaduermael
public_repos75
account_age_days4 530
Виключено з оцінювання (немає даних або не застосовно): Верифікований домен. Залишкові ваги перенормовано.

Інженерна якість

Чи наявні базові інженерні практики та документація?

81Добрий · 20% загального індексу
Як обчислюється оцінка
24/24Процеси CI — 5 процес(ів) CI
24/24Наявні тести
0/16Конфігурація лінтера
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

Готовність до ШІ

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Незалежний, експериментальний бейдж — вага 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Читабельна історія комітів — намір зазначено у 87 з 100 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
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/11Конфігурація лінтера / форматера
11/11Статична перевірка типів — Go (статично типізована)
10/10Відтворюване середовище — Dockerfile, lockfile
10/10Підтверджена практика роботи з агентами — 13 з останніх 100 комітів створено агентом або з його зазначенням
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Керовані розміри файлів — 8/241 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languageGo
largest_source_bytes182 845
source_files_sampled241
oversized_source_files8

Ключові факти

218зірок GitHub
5контриб'юторів
956комітів за останні 12 місяців
0днів від останнього пушу
16релізів
1бас-фактор
15відкритих issue
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

Докладніше

Історія зірок і форків 0 ★ / 9 ⇿
0Зірки
9Форки
14Релізи

Коли додано кожну зірку й форк — зібрано з 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 — повна методологія · вікі метрик.

Як окремий результат виглядає на тлі всього реєстру: сукупна статистика.