Публічний реєстр
Звіт про здоров'я програмного забезпеченнясхема 0.27.0 · метрики 1.13.0 · 2026-07-28 03:43 UTC

bishnu133 / bubblegum

PythonMIT★ 0 зірок⑂ 0 форківз квіт. 2026 р.Переглянути на GitHub ↗

bishnu133/bubblegum має індекс здоров’я 54 зі 100, що відповідає смузі «Помірний». Найвищий показник — Vitality (83/100), найнижчий — Community & Adoption (24/100). Останнє оновлення — сьогодні. Більшість нещодавньої роботи виконує один учасник.

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

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

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

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

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

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

Власність

bishnu133Особистий обліковий запис
0 підписників5 публічних репозиторіївз лист. 2024 р.

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

Пакетні екосистеми

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікація
PyPIbubblegum-ai0.0.6a61-610 днів тому

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

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

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

83Добрий · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 0 дн. тому
8.3/36Ритм комітів — 12/52 тижнів із комітами
18/18Обсяг комітів — 375 комітів за останній рік
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Використані вхідні дані
commits_last_year375
human_commit_share1
days_since_last_push0
active_weeks_last_year12
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 6 релізів
36/36Свіжість релізів — останній реліз 41 дн. тому
27/27Ритм релізів — реліз кожні ~8,2 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count6
latest_release_tagv0.0.6-alpha
releases_from_tagsні
days_since_latest_release41
mean_days_between_releases8,2
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

Спільнота та впровадження

Чи має проєкт користувачів, завантаження, увагу та влаштовані умови для контриб’юторів?

24Критичний · 18% загального індексу
Як обчислюється оцінка
0/60Зірки — 0 зірок
0/25Форки — 0 форків
0/15Спостерігачі — 0 спостерігачів
Використані вхідні дані
forks0
stars0
watchers0
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ні

Сталість та врядування

Чи переживе проєкт своїх людей — бас-фактор, реактивність, хто за ним стоїть і як супроводжуються пакети?

51Помірний · 24% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
7.9/22.5Розподіл комітів — головний контриб’ютор — автор 65% комітів
4.1/13.5Широта контриб’юторів — 3 контриб’юторів
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Використані вхідні дані
bus_factor1
contributors_sampled3
top_contributor_share0,65
Як обчислюється оцінка
0/46.8Вирішення issue — немає issue або даних
38.2/38.3Прийняття PR — злито 244/244 вирішених PR
0/15OpenSSF Scorecard: Code-Review — Found 0/11 approved changesets -- score normalized to 0
Використані вхідні дані
merged_prs244
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Виключено з оцінювання (немає даних або не застосовно): Вирішення issue. Залишкові ваги перенормовано.
Як обчислюється оцінка
10/30Підтримка власника — особистий (користувацький) обліковий запис
0/20Верифікований домен — не застосовно до користувацьких облікових записів
0/25Охоплення власника — 0 підписників у bishnu133
9.1/25Послужний список — 5 публічних репозиторіїв, вік облікового запису ~1 р.
Використані вхідні дані
followers0
owner_typeUser
is_verified
owner_loginbishnu133
public_repos5
account_age_days623
Виключено з оцінювання (немає даних або не застосовно): Верифікований домен. Залишкові ваги перенормовано.

Супровід пакетів

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 1 пакет(ів) у pypi
35/35Свіжість публікацій — остання публікація 0 дн. тому
20/20Історія версій — 61 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packagesbubblegum-ai
ecosystemspypi
any_deprecatedні
min_days_since_publish0

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

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

63Помірний · 20% загального індексу
Як обчислюється оцінка
24/24Процеси CI — 5 процес(ів) CI
24/24Наявні тести
0/16Конфігурація лінтера
0/9.6Pre-commit-хуки
0/6.4.editorconfig
14/20OpenSSF Scorecard: CI-Tests — 8 out of 11 merged PRs checked by a CI test -- score normalized to 7
Використані вхідні дані
has_ciтак
has_testsтак
has_editorconfigні
has_linter_configні
has_precommit_configні

Документація

65Помірний
Як обчислюється оцінка
30/30README
25/25Каталог документації
0/15Сайт документації / домашня сторінка
0/10Опис репозиторію
0/10Теми
10/10Wiki
Використані вхідні дані
topics
has_wikiтак
homepage
has_readmeтак
has_docs_dirтак
has_descriptionні

Безпека

Чи міцні видимі практики безпеки й ланцюга постачання, без непослабленої пов’язаності з юрисдикціями високого ризику?

44У зоні ризику · 16% загального індексу

Стан безпеки

44У зоні ризику
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
1.8/2.5CI-Tests — 8 out of 11 merged PRs checked by a CI test -- score normalized to 7
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/11 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
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 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
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 — немає даних
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4,4
Виключено з оцінювання (немає даних або не застосовно): signed_releases. Залишкові ваги перенормовано.

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

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Незалежний, експериментальний бейдж — вага 0.0, тож він подається окремо і не впливає на загальний індекс здоров'я.

52Помірний · 0% загального індексу
Як обчислюється оцінка
0/45Інструкції для агентів — немає CLAUDE.md / AGENTS.md / правил редактора
0/15Машиночитана документація (llms.txt)
40/40Читабельна історія комітів — намір зазначено у 90 з 100 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,9
agent_instruction_files
agent_instruction_max_bytes
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
0/11Конфігурація лінтера / форматера
11/11Статична перевірка типів — clients/node/tsconfig.json
10/10Відтворюване середовище — lockfile
10/10Підтверджена практика роботи з агентами — 77 з останніх 100 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
1/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
Використані вхідні дані
has_nixні
has_testsтак
lockfilespackage-lock.json
has_dockerfileні
typed_languageні
bootstrap_files
has_devcontainerні
has_linter_configні
typecheck_configsclients/node/tsconfig.json
agent_commit_share0,77
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
27/45Типізований код — Python з конфігурацією перевірки типів (clients/node/tsconfig.json)
54.2/55Керовані розміри файлів — 6/425 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languagePython
largest_source_bytes160 075
source_files_sampled425
oversized_source_files6
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
0/20Сервер MCP
40/40Придатні до запуску приклади — examples
Використані вхідні дані
example_dirsexamples
has_mcp_signalні
api_schema_files

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

0зірок GitHub
3контриб'юторів
375комітів за останні 12 місяців
0днів від останнього пушу
6релізів
1бас-фактор
0відкритих issue
PyPIпакетних екосистем

Попередження щодо збору даних

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:bubblegum-ai@0.0.6a61; advisories assessed against the repository dependency graph instead

Докладніше

OpenSSF Scorecard 4.4 / 10
4.4сукупно

Незалежна, не прив'язана до інструментів оцінка безпеки від відкритого проєкту OpenSSF Scorecard. Кожна перевірка винагороджує практику безпеки, а не інструмент конкретного постачальника. Перевірки, які Scorecard не зміг визначити, позначено н/д і виключено з оцінки безпеки (вони ніколи не зараховуються як нуль).Scorecard v5.5.0 · 2026-07-28 03:42 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
7CI-Tests8 out of 11 merged PRs checked by a CI test -- score normalized to 7
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/11 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
1Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 1
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
н/дSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Прямі залежності 2
РеєстрПакетОбмеження версіїМаніфест
PyPIpydantic>=2.0pyproject.toml
PyPIpyyamlpyproject.toml
Усі залежності не зібрано

Не вдалося зібрати розв'язаний набір залежностей для цього звіту: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 3126,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "HTML": 41951,
        "Shell": 6421,
        "Python": 2878119,
        "JavaScript": 18304,
        "TypeScript": 30234
      },
      "pushed_at": "2026-07-28T03:40:47Z",
      "created_at": "2026-04-28T08:41:29Z",
      "owner_type": "User",
      "updated_at": "2026-07-28T03:41:10Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "User",
      "login": "bishnu133",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/188071550?v=4",
      "created_at": "2024-11-11T14:22:23Z",
      "is_verified": null,
      "public_repos": 5,
      "account_age_days": 623
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.0.6-alpha",
          "kind": "prerelease",
          "published_at": "2026-06-16T03:45:59Z"
        },
        {
          "tag": "v0.0.5-alpha",
          "kind": "prerelease",
          "published_at": "2026-05-11T06:07:20Z"
        },
        {
          "tag": "v0.0.4-alpha",
          "kind": "prerelease",
          "published_at": "2026-05-10T13:33:36Z"
        },
        {
          "tag": "v0.0.3-alpha",
          "kind": "prerelease",
          "published_at": "2026-05-09T11:16:09Z"
        },
        {
          "tag": "v0.0.2-alpha",
          "kind": "prerelease",
          "published_at": "2026-05-08T16:12:47Z"
        },
        {
          "tag": "v0.0.1-alpha",
          "kind": "prerelease",
          "published_at": "2026-05-06T06:43:03Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "3d182208e550227f614f9102febab019c5d78b3a",
          "body": "… forms (0.0.6a61)\n\nfix(web): stop text values piling into the first input on unlabeled forms (0.0.6a61)",
          "is_bot": false,
          "headline": "Merge #246: stop text values piling into the first input on unlabeled…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-28T03:40:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "064c13f32be7fc0aaa2e39bbc215a5ab0cc452c1",
          "body": "…orms (0.0.6a61)\n\nOn a form whose Ant inputs have no accessible name (labels use for= ids the\ninputs don't carry — only data-testid), every `Enter \"X\" into <field>` step\nlanded in the first input. Three causes, all fixed:\n\n1. Nameless role=textbox was silently filled at .first. The executor's\n   str\n[…]\nb.py\nand a nameless-role parser unit test. Engine 0.0.6a60 -> 0.0.6a61.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JbYANheWt84xD7vf3N4w4K",
          "is_bot": false,
          "headline": "fix(web): stop text values piling into the first input on unlabeled f…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-28T03:40:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "69158c0f1031c0d1c9873acd99cda88a080af655",
          "body": "…rection (0.0.6a60)\n\nfix(web): don't undo a committed multi-select value during self-correction (0.0.6a60)",
          "is_bot": false,
          "headline": "Merge #245: don't undo a committed multi-select value during self-cor…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-27T16:54:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "238b1d5835fce38708641db195e0f4b6272fe21e",
          "body": "…ction (0.0.6a60)\n\nA multi-select step could log `passed` while the value ended up NOT selected\n(the option briefly committed, then vanished; dropdown left open). In\n_select_single's self-correcting probe, grounding resolves the field to its\ninner role=combobox <input> while _other_select_triggers r\n[…]\nremove control + inner\nrole=combobox ref). Engine 0.0.6a59 -> 0.0.6a60.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JbYANheWt84xD7vf3N4w4K",
          "is_bot": false,
          "headline": "fix(web): don't undo a committed multi-select value during self-corre…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-27T16:54:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "78bdea68543601d52681be34dffb868f512fecc1",
          "body": "…6-alpha.13)\n\nThe Node client spawned `python -m bubblegum.bridge` resolved against the Node\nprocess PATH. When a tester pip-installed the engine into an activated venv but\nthe Node runner's PATH didn't point at that venv (IDE runners, npx, a shell that\ndidn't re-activate), the bridge silently ran a\n[…]\n tests.\n\nEngine unchanged; npm client 0.0.6-alpha.12 -> 0.0.6-alpha.13.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JbYANheWt84xD7vf3N4w4K",
          "is_bot": false,
          "headline": "fix(node): run the engine bridge from the active virtualenv (npm 0.0.…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-27T15:17:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "263035c93df22a8365954cd11ddd39df391999b4",
          "body": "…label (0.0.6a59)\n\nfix(web): verify multi-select commit even when the field is grounded to its label (0.0.6a59)",
          "is_bot": false,
          "headline": "Merge #244: verify multi-select commit when field is grounded to its …",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-27T10:50:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "49b2b4deadc74fc0b43c8e58b5b6a08e476878dc",
          "body": "…to its label (0.0.6a59)\n\nA multi-select step could log `passed` while nothing was actually selected.\nThe \"did the click add a selection tag?\" verification (`_value_committed`)\nonly ran when the resolved trigger element was itself inside `.ant-select`\n(`_is_ant_select`). Grounding often resolves a f\n[…]\nust pass, in-widget non-commit\nmust fail). Engine 0.0.6a58 -> 0.0.6a59.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JbYANheWt84xD7vf3N4w4K",
          "is_bot": false,
          "headline": "fix(web): verify multi-select commit even when the field is grounded …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-27T10:44:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2bc832804f5592d1dc2a989d73b52523c0536627",
          "body": "…eholders (0.0.6a58)\n\nchore: replace app-specific sample identifiers with generic placeholders (0.0.6a58)",
          "is_bot": false,
          "headline": "Merge #243: replace app-specific sample identifiers with generic plac…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-22T08:25:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9190370b330bde3f0b9f97f56635f747360df5fb",
          "body": "…ers (0.0.6a58)\n\nDocs, tests, example fixtures, and changelog history referenced identifiers from\na specific application under test. They carried no behavior (sample data only)\nand are replaced throughout with neutral placeholders — generic app/label names,\nRecordID table columns, appium.example.com\n[…]\ngine 0.0.6a57 -> 0.0.6a58; npm client\n0.0.6-alpha.11 -> 0.0.6-alpha.12.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "chore: replace app-specific sample identifiers with generic placehold…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-22T08:25:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bb492870652f987325cef0621b29ddf582388569",
          "body": "… (0.0.6a57)\n\nfix(mobile): exact-label preference so \"Allow\" wins over \"Don't Allow\" (0.0.6a57)",
          "is_bot": false,
          "headline": "Merge #242: exact-label preference so \"Allow\" wins over \"Don't Allow\"…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-22T08:06:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a941559d5a8cff51ec5d332bf3de0addf5d58c48",
          "body": "…\" (0.0.6a57)\n\niOS system permission alerts show Allow next to Don't Allow, and both contain\nthe substring \"allow\" — so the bidirectional substring match returned both as\nequal-confidence candidates, risking a tap on deny.\n\n- AppiumHierarchyResolver now scores match exactness. An exact label/name/va\n[…]\n guide.\n\nEngine-only; no TS client change. Engine 0.0.6a56 -> 0.0.6a57.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "fix(mobile): exact-label preference so \"Allow\" wins over \"Don't Allow…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-22T08:06:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "61b0d547cde64e58e25387c9d17d3c36e3df0762",
          "body": "….6a56)\n\nfeat(mobile): iOS grounding + attach to an existing Appium session (0.0.6a56)",
          "is_bot": false,
          "headline": "Merge #241: iOS grounding + attach to an existing Appium session (0.0…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-22T02:09:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db88160af758584e72414a457faedc822cee9c7d",
          "body": "….0.6a56)\n\nEnable the iOS pilot: resolve iOS elements by human text, and run an in-test\nBubblegum fallback against a cloud device (pCloudy/BrowserStack) where only one\nAppium session per device is allowed.\n\niOS grounding\n- AppiumHierarchyResolver now reads XCUITest attributes (label/name/value/type,\n[…]\ngine 0.0.6a55 -> 0.0.6a56; npm client\n0.0.6-alpha.10 -> 0.0.6-alpha.11.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(mobile): iOS grounding + attach to an existing Appium session (0…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-22T02:03:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cc12a4afb47185c72d7c768fc7c8372881e724a6",
          "body": "feat(report): one combined report — Summary tab + per-test collapsible details (0.0.6a55)",
          "is_bot": false,
          "headline": "Merge #240: one combined report — summary + per-test details (0.0.6a55)",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-21T07:52:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "edea7294ea7070b7d4b8cb02b9a31ca179f4b80b",
          "body": "…e details (0.0.6a55)\n\nFollow-up to the a54 summary. The `summary` report is now ONE combined,\nself-contained HTML with two tabs:\n- Summary: every test with pass/self-healed/fail/skip counts + grand totals.\n- Test details: one collapsible <details> per test, each embedding that test's\n  full step-by\n[…]\nha.10.\n1992 unit + 18 node tests pass; build + twine + node pack clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(report): one combined report — Summary tab + per-test collapsibl…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-21T07:52:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "718907223cc05a47ba70ddb7746ce87616cf29cf",
          "body": "….6a54)\n\nfix(log)+feat(report): quiet recovered-step error; cross-run suite summary (0.0.6a54)",
          "is_bot": false,
          "headline": "Merge #239: quiet recovered-step error + cross-run suite summary (0.0…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-21T07:16:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "963dfcd8afdfce9b6d2618eac2dd1aaae8bcb713",
          "body": "…mmary (0.0.6a54)\n\nTwo reporting improvements from real-app feedback.\n\n1. Recovered steps no longer log a scary \"Execution failed\" ERROR. The adapter\n   logged `Execution failed for ref=...` at ERROR before the SDK's recovery\n   decision, so a step that ultimately PASSED (recovered) looked failed in\n[…]\n 18 node tests pass; build + twine check pass; node build + pack clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "fix(log)+feat(report): quiet recovered-step error; cross-run suite su…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-21T07:16:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "590c5c0a5e56a85385db296924f862cb1019bd04",
          "body": "fix(web): don't type into a disabled same-named field behind an open modal (0.0.6a53)",
          "is_bot": false,
          "headline": "Merge #238: fix(web) disabled same-named field behind modal (0.0.6a53)",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-21T04:11:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "94a436745d75c8d0fa92953530386dda0ee78d05",
          "body": "…(0.0.6a53)\n\nFollow-up to a52 for the popup-input flake on the \"Add a Product\" modal. Typing\ninto the modal's HealthPoints field timed out because grounding matched a\nDISABLED same-named spinbutton (id=\"hpBudget\") on the page behind the modal —\nPlaywright's .first picks the earlier-in-DOM element, w\n[…]\n984 unit tests pass; build + twine check pass; node build + pack clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "fix(web): don't type into a disabled same-named field behind a modal …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-21T04:10:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cb349e57d0fb024a0bdcc27d515030f2e2b7c2c0",
          "body": "fix(web): recover custom-select steps grounded by AI but not executable (0.0.6a52)",
          "is_bot": false,
          "headline": "Merge #237: fix(web) recover custom-select execution failures (0.0.6a52)",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-21T03:57:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6b2ee77209562839b9d14173e5e8c67c74267b4a",
          "body": "…le (0.0.6a52)\n\nFixes a flake introduced by wiring the AI grounding tier in a51. On custom\nrole=combobox selects (Ant/MUI/CDK) whose accessible name differs from the\nvisible label, llm_grounding can return a confident ref\n(role=combobox[name=\"Recommendation Tags\"]) that doesn't resolve on the page,\n\n[…]\n build + pack\nclean. New tests/unit/test_execution_failure_recovery.py.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "fix(web): recover custom-select steps grounded by AI but not executab…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-21T03:54:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c452a9e9fc9b64a7873a4d01a6f7c7c467906a89",
          "body": "AI grounding overhaul (0.0.6a51) — real AI fallback, semantic tier, self-hosted vision, resilience, observability",
          "is_bot": false,
          "headline": "Merge #236: AI grounding overhaul (0.0.6a51)",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-21T01:38:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9deda01988b29e508188159a0dd19e79412f094",
          "body": "- Bump engine to 0.0.6a51 (pyproject, __version__) and npm client to\n  0.0.6-alpha.6 (package.json + lockfile); update the pinned version test.\n- CHANGELOG: 0.0.6a51 entry summarizing tasks 1-9.\n- New docs/ai-grounding-enhancements.md: what changed, per-tier setup,\n  real-app testing (web + mobile),\n[…]\nss; python -m build + twine check\npass; npm build + pack dry-run clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "release: 0.0.6a51 / npm 0.0.6-alpha.6 — AI grounding overhaul + docs",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T14:21:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7af7ad9abf244e80e3bbf55e81b69b1e94b3997c",
          "body": "Reflects the decision to pause the code-generator features and focus on\nweb/mobile automation + AI grounding. Documentation and help-text only — no code\nbehaviour, CLI, config, or output changes; both commands remain available and\nsupported for existing users.\n\n- README roadmap: current focus + paus\n[…]\n`record` and `convert` CLI help/description\n  so it surfaces in --help.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "docs: mark code generator (record + convert) as paused/maintenance mode",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T14:04:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "85572c0b41c3a424772b877e39fdfcf9cc5bb529",
          "body": "Adds the streaming half of observability (the end-of-run Allure/JSON/JUnit/HTML\nreports and `explain` already existed): every step emits a structured,\nmachine-readable observation as it happens, for dashboards / APM / audit logs.\n\n- core/observability.py: pluggable sinks — JSONLFileSink (one JSON li\n[…]\nault; no behaviour change out of the box. Full unit suite green (1979).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(observability): streaming per-step observations + replay mode",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T14:01:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a55896319dd75a77d66b6a92410b711206ceeb4e",
          "body": "…bing\n\nHardening + consolidation of the provider stacks. (Deliberately did NOT do a\nwholesale interface merge of text complete() and vision detect_targets() — a\nrisky rewrite for modest gain; instead consolidated the genuinely duplicated\nplumbing and added the enterprise-robustness pieces.)\n\n- Resil\n[…]\n new fields default to today's behaviour. Full unit\nsuite green (1967).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(models): provider resilience, config-driven pricing, shared plum…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T10:14:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2d1b9af0c57efb9cc35a2bc2f11ad3c836eac77f",
          "body": "…mobile\n\nMakes screenshot grounding a config-selectable, self-hostable tier that feeds\nthe existing screenshot -> candidates -> hydrate-to-durable-ref -> cache\npipeline — the seam for OmniParser / UI-TARS / computer-use style models.\n\n- HTTPGroundingProvider: self-hosted grounder backend (stdlib url\n[…]\none); no behaviour change out of the box.\nFull unit suite green (1955).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(vision): pluggable screenshot-grounding backend, first-class on …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T10:02:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fa2707d11cf1e5792ea3591592bef6590ca732d9",
          "body": "…loop\n\nThe engine was async but ran resolvers synchronously, and the LLM resolver\nspun up a throwaway ThreadPoolExecutor + asyncio.run() on every call — a new\nthread and event loop per grounding request.\n\n- Resolver ABC gains resolve_async(); the default delegates to sync resolve()\n  with zero overh\n[…]\nrdering); this is a\nplumbing/perf change. Full unit suite green (1942).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "perf(grounding): async resolver contract; drop per-call thread/event-…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T09:52:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "78da2fcbb13b9e7f4bd87d851a0d2751340cf99c",
          "body": "Adds a semantic matcher between fuzzy (edit-distance) and the LLM tier that\ncatches meaning-level label drift (\"Submit\"->\"Continue\", \"Delete\"->\"Move to\nTrash\") which lexical matching misses — resolving those cases faster and cheaper\nthan an LLM call, before the LLM tier is reached.\n\nEnterprise-safe \n[…]\ncuits on a strong\nlexical hit; semantic only fires on the harder cases.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(grounding): embedding-based semantic Tier-2 resolver + cache",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T09:45:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9edba79e933d614ff9f6dddba57967d75ebdd6c4",
          "body": "Replace the brittle \"respond with ONLY JSON\" + markdown-fence-stripping\ncontract with provider-native guaranteed-schema output, so the model can no\nlonger return unparseable text that silently becomes a false \"no match\".\n\nContract:\n- ModelProvider.complete() gains an optional normalized `json_schema\n[…]\ns _DECOMPOSE_SCHEMA ({action_type enum, target_phrase,\n  input_value}).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(models): guaranteed-schema structured output / tool-use",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T09:27:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "311d3a41bd8d586ebfa82870e58b1d42243a0a3e",
          "body": "Provider-agnostic speed/cost/accuracy improvements behind the ModelProvider\nabstraction, each applied where the provider supports it.\n\nConfig (AIConfig, backward-compatible — all new fields optional):\n- fast_model / strong_model: fast handles grounding + decompose; strong is an\n  optional escalation\n[…]\ny when escalation is enabled and a distinct strong model is configured.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(models): prompt caching + tiered model routing + call tuning",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T09:17:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a695764dfee827f4b07b6b814be84d4af7fc6b58",
          "body": "The registry built LLMGroundingResolver in stub mode (provider=None) and\nnothing ever injected a real provider, so Tier-3 text grounding silently\nreturned [] in production — the documented \"AI when deterministic resolvers\nfail\" behaviour never fired, and every UI edge case became a hand-coded\ndeterm\n[…]\nso the\nnext run replays it as a Tier-1 cache hit with zero model calls.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GpNWs6SZxcUPVJTyJsLPgV",
          "is_bot": false,
          "headline": "feat(grounding): wire the LLM grounding tier live + reachable by default",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-20T08:59:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "01ee872bbcfb49c640fc234709924f8bd8622f33",
          "body": "…ion click (a50)\n\n`Select ... from \"Drink Bonus Type\" drop down` still committed into the Food\npanel once Food's \"Bonus Type\" was already set. Two distinct bugs:\n\n- Panel qualifier is now decisive. Ant gives a select that already displays the\n  wanted value a large \"shows the value\" bonus, which out\n[…]\nts\nto Drink). Browser-verified end-to-end. Engine 0.0.6a49 -> 0.0.6a50.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): named-panel dropdown beats already-selected twin; scope opt…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-15T08:39:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eb61ba3a10bd42dd1005c75b642869f7fb0683b8",
          "body": "…ns (a49)\n\n`Select ... from \"Drink Bonus Type\" drop down` still landed in the Food panel's\ndropdown: the \"Bonus Type\" select carries neither \"bonus\" nor \"type\" in its id\nand its column header is shared across both panels, so Food-vs-Drink rested on\none weak id token and Food edged ahead in the live \n[…]\nto-end against the real captured page DOM. Engine 0.0.6a48 -> 0.0.6a49.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): panel-name qualifier for repeated dropdowns across accordio…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-15T07:38:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d0a3dbb6b7bc845b30de9f8d13c12460915a869e",
          "body": "Two controls on the Rewards/Gamification page still resolved to the wrong twin.\n\n- Number field with only a placeholder: a \"Stamp Position\" range input (bare\n  <span> label, accessible name only from placeholder \"Position\") exists in both\n  a Food and a Drink panel. With no <label> the input finder \n[…]\nto-end against the real captured page DOM. Engine 0.0.6a47 -> 0.0.6a48.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): placeholder-only fields & shared column-header dropdowns (a48)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-15T07:11:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "34ade46df42a82585e72996e1a1ded68f2ecff07",
          "body": "…a47)\n\nA Rewards/Gamification page repeats labels across sections and inside\ndefault-collapsed accordion panels, so several steps hit the wrong control.\n\n- New collapse/expand resolver: a \"Click on \\\"Drink\\\" button to expand Drink\n  section\" step now pins the Ant .ant-collapse-header (MUI AccordionS\n[…]\nrified against the real\ncaptured page DOM. Engine 0.0.6a46 -> 0.0.6a47.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): expand the right accordion panel; section-aware dropdowns (…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-15T03:52:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d523547c3fd8c9a673681144371a89bee51bf5f0",
          "body": "A step \"Click on \\\"Add\\\" button\" failed: an Ant modal was open and its footer\n\"Add\" button shares its label with the page's #add-basket-button behind the\nmodal mask. Grounding (memory_cache) resolved the page copy, and the\n.ant-modal-wrap mask intercepts the click -> 10s timeout.\n\nThe dialog-click p\n[…]\nl unit + browser modal regression;\nfull unit suite green (1908 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Click the button inside an open modal, not its masked twin (a46)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-15T02:07:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1994df597fd471e84d313b96479ab15578867077",
          "body": "…_phrase (a45)\n\nRoot cause, proven from the run's own data: for BOTH \"Male\" steps find_radio\nreturned `.ant-radio-wrapper:has(input[id=\"recommendationRules_female\"])` — the\nLAST radio in the DOM. That only happens when the option score is 0 for every\nradio, i.e. the phrase handed to the resolver was\n[…]\negressions for radio\nand checkbox; full unit suite green (1905 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Radio/checkbox use the quoted option, not the client's section target…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T12:34:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d24fbfaa6877c9d43d97bb3f0af5dc518babd7ff",
          "body": "… (a44)\n\nRoot cause, confirmed against the real DOM the user provided: the radio/checkbox\nresolvers marked the target with a temporary `data-bg-radio`/`data-bg-checkbox`\nattribute and returned `[data-bg-radio=\"1\"]`. The React app re-renders between\nresolution and the click and strips unknown attribu\n[…]\nurvives-rerender regression added; full unit suite green\n(1905 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Radio/checkbox return a stable id-based selector (survives re-render)…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T12:04:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9a3e583186b0cdc7aa68b6cc0803c154a685c360",
          "body": "Diagnosed from the run's screenshots: the \"Male for Eligibility\" step scrolled to\nthe Recommendation card, and the real Ant form nests the radio ~12 levels below\nits .ant-card.\n\n1. Eligibility Male hit the wrong section (again). Section detection climbed a\n   BOUNDED number of ancestors (8) to find \n[…]\ntolerant multi-select regressions;\nfull unit suite green (1905 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Depth-independent section titles + space-tolerant option match (a43)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T08:43:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5ea8045de94c52c7d7ab7c565af54875921e9c51",
          "body": "Diagnosed from the run's screenshots (Eligibility Sex still \"All\"; the tags step\nleft a stray dropdown open in the Recommendation area, ~44s).\n\n1. Eligibility Male hit the wrong section. The real form uses GENERIC radio ids\n   (rc_radio_*) and a shared \"Sex\" label, so the only discriminating word is\n[…]\nsion + multi-select speed covered; full\nunit suite green (1905 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Robust section-title detection + fast multi-select add (a42)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T07:35:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dea3ca35fda6969ec66b2b34a0462e0f1c6b6c32",
          "body": "Follow-up to a40 on the two-section EDSH form.\n\n1. \"Division Name\" still ran twice / ~28s. Grounding resolves the select to its\n   INNER <input role=combobox> (accessible name), but `_selected_texts` queried\n   that input's descendants — where the `.ant-select-selection-item` never lives —\n   so eve\n[…]\n disambiguation regressions added; full\nunit suite green (1905 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Fix combobox root climb, id/name section signal, multi-select tags (a41)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T07:03:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "265901b0a0f556e5349ab3d9a16707d8af0ca126",
          "body": "…(a40)\n\nFollow-up to a39 on the two-section (Eligibility/Recommendation) EDSH form.\n\n1. Recommendation Age wrote into Eligibility fields. The text-input resolver had\n   no section awareness AND only ran as a grounding fallback, so when the a11y\n   snapshot resolved a duplicated \"Minimum Age\" as \"uni\n[…]\no-double-commit\nregressions added; full unit suite green (1905 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Section-aware inputs, robust section headings, safe dropdown commits …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T03:24:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dca62db1bb659184c247934403796a8456e410c4",
          "body": "…a (a39)\n\nThree field-reported issues on forms with two similar sections (Eligibility /\nRecommendation) that share option labels and tag dropdowns:\n\n1. Section disambiguation. \"Select Male radio for Eligibility\" landed on the\n   Recommendation section: the resolvers scored by option label only, so b\n[…]\nch fakes for the new\ncommit probe. Full unit suite green (1902 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "Section-aware radio/checkbox + committed dropdown picks + openai extr…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-14T02:24:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "00d9584d5135c087285c95c69a02509d790a9628",
          "body": null,
          "is_bot": false,
          "headline": "Merge: checkbox resolver + quoted-target fallbacks; release 0.0.6a38",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T15:39:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e098da808c00510a9d5a85dfb19a84e5acb2a008",
          "body": "…opdowns, checkboxes; release 0.0.6a38\n\nThree issues on the Participating-Details / Metrics steps, all rooted in\ndeterministic parsing dropping or mangling the target:\n\n1) Checkbox selection failed (\"Select \\\"Food purchase\\\" checkbox\" scored 0.57).\n   Ant/MUI hide the real <input> inside a styled <l\n[…]\n Adds unit + browser-gated regression tests.\nBumps version to 0.0.6a38.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "feat(web): checkbox resolver + quoted-target fallbacks fix radios, dr…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T15:39:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a847b4b889ea8b15880630ef60e4adb32e2ca36d",
          "body": null,
          "is_bot": false,
          "headline": "Merge: non-destructive self-correcting dropdown + release 0.0.6a37",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:48:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "98eb6ddc1dc9a9aaa65bf7f1a521c29f82128368",
          "body": "…n the wrong combobox; release 0.0.6a37\n\na36's value-as-ground-truth fallback fixed selecting the right dropdown, but\nprobing a wrongly-scored select (e.g. \"Challenges Joined\") could leave a stray\nselection behind — some Ant selects auto-commit their active option on blur, so\nthe first option (\"Test\n[…]\nsserts the mis-scored select is left clean.\n\nBumps version to 0.0.6a37.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): self-correcting dropdown must not leave a stray selection i…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:48:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cb88b6eb79a2fb2336091c13d079553c17f0b630",
          "body": null,
          "is_bot": false,
          "headline": "Merge: self-correcting dropdown selection + release 0.0.6a36",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:27:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c50aa7f8e42108e94d76f8a9b895ba46c32f13e",
          "body": "… actually offers the value; release 0.0.6a36\n\nA group heading like \"Eligibility Tags\" labels several selects, and label\nscoring can pick the wrong one (e.g. the neighbouring \"Challenges Joined\"),\nwhere the value doesn't exist — the run then types into the wrong field and\nfails. Rather than chase th\n[…]\neighbour has it -> selection self-corrects). Bumps version to 0.0.6a36.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): self-correcting dropdown selection — pick the combobox that…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:27:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fda0cfa171a656805e50f40ef77ac7901b9cb286",
          "body": null,
          "is_bot": false,
          "headline": "Merge: revert picker-OK click, keep combobox filter; release 0.0.6a35",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:15:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6fc6e043af5a213863bfd76a93ec15269ee1c23f",
          "body": "…pe-to-filter; release 0.0.6a35\n\nThe a34 \"click the picker OK button\" step was a misdiagnosis — the date failures\nwere caused by the caller's date formatting, not a missing commit, and clicking\nOK is not required (Enter commits). An extra click on the open picker panel can\ninterfere with a working r\n[…]\nter fix (the real remaining issue) is kept.\n\nBumps version to 0.0.6a35.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): drop unnecessary datetime-picker OK click; keep combobox ty…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:15:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "19fc1dcf4aec80e458d53a02603bf99e68e01398",
          "body": null,
          "is_bot": false,
          "headline": "Merge: datetime OK + combobox filter fixes + release 0.0.6a34",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:11:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32a8c6dfbe26d9b729b5734f5517978cb4b93053",
          "body": "…comboboxes; release 0.0.6a34\n\nTwo follow-ups on the Participating-Details step:\n\n1) Date range values were entered in the right inputs (a33) but never committed:\n   an Ant datetime RangePicker keeps its panel open with an OK button and Enter\n   alone does not confirm. `type` on a picker input now c\n[…]\ndds browser-gated regression tests for both. Bumps version to 0.0.6a34.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): commit datetime pickers via OK + type-to-filter searchable …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T09:10:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "503013a0c061f81778d850cfa46743b3a10b3219",
          "body": null,
          "is_bot": false,
          "headline": "Merge: nested-Ant label association fixes + release 0.0.6a33",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T08:49:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a8c5f9df925240374ddb193d195e3b4f18a733d0",
          "body": "…oup-heading selects; release 0.0.6a33\n\nTwo Participating-Details failures, both the same recurring root cause — a\ncontrol's OWN label being mistaken for the field label in nested Ant layouts:\n\n1) Date ranges overwrote each other. The Registration range picker sits in a\n   form-item that also holds \n[…]\ndds browser-gated regression tests for both. Bumps version to 0.0.6a33.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): field-label resolution ignores control-internal labels + gr…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-13T08:49:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a685d3579f44af63e28145fcaa8d2378bc689a86",
          "body": null,
          "is_bot": false,
          "headline": "Merge: Quill toolbar label fix + release 0.0.6a32",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-11T12:40:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aadb378b5e36e5c8285a8d8709f4e8271e27d32e",
          "body": "…el + release 0.0.6a32\n\nThe label-climb helper treated any element matching [class*=\"label\"] as the\nfield's label. A rich-text editor's own toolbar contains .ql-picker-label spans\n(Quill header/color/align pickers), so the climb stopped on the inner\n.ant-form-item-control-input-content wrapper and r\n[…]\nsion fixture so this exact case is\ncovered.\n\nBumps version to 0.0.6a32.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): don't mistake Quill toolbar picker labels for the field lab…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-11T12:40:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e3848f3ae900236673ced09c2d9cc557677e5f5d",
          "body": "… 0.0.6a31\n\nThe a30 rich-text pre-resolver only claimed a contenteditable editor on an\nexact, full-token label match. When the target phrase was decomposed with any\nextra/fewer/reordered words, it returned nothing and the step fell back to the\na11y mis-match (typing into a nearby valued input, then \n[…]\nthis Challenge section\", \"About this Challenge details\",\n\"Key Detail\").\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): make rich-text resolver robust to phrase variance + release…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-11T12:26:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "801d51fcee569a68ae2a47235d6bfd8c950b2923",
          "body": "…0.0.6a30",
          "is_bot": false,
          "headline": "Merge: generic rich-text (contenteditable) editor handling + release …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-10T09:08:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fcfffbe31c1a4ac81830078ebcd1e0f61b9e8cc",
          "body": "…lease 0.0.6a30\n\nA \"type into <label>\" step targeting a rich-text editor (Quill/TinyMCE/\nProseMirror/CKEditor — a bare `[contenteditable]` div) failed: these have no\n`textbox` role and no accessible name, so name-based grounding can't see them.\nThe a11y chain then mis-matched a nearby valued input —\n[…]\nr-gated behavioural test covering both editors and the no-hijack guard.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): handle rich-text (contenteditable) editors generically + re…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-10T09:08:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "576a393e6f900dfea26c22dd29946075f85554aa",
          "body": null,
          "is_bot": false,
          "headline": "Merge: Ant nested-label input fix + release 0.0.6a29 (#pending)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-10T08:47:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7cbe0e70dd60b20a5132ecd0552bfec28545a35f",
          "body": "Bumps version in the three tracked places (pyproject.toml,\nbubblegum/__init__.py, tests/unit/test_package_metadata.py) for the a29\nrelease carrying the Ant Design nested form-item label fix.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "release: 0.0.6a29 — fix Ant nested-label input resolution",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-10T08:47:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "84179353aea6d852e37a06a48e38dbc24b8a04bb",
          "body": "The DOM fallback that scores text inputs / dropdowns / date-range / file\ninputs by their form-item label used `e.closest('[class*=\"form-item\"]')`.\nAnt Design wraps every control in `.ant-form-item-control-input-content`,\nwhose class name also contains the substring \"form-item\", so `closest()`\nstoppe\n[…]\nrowser-gated behavioural test that\nreproduces the Ant nested-label DOM.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01F2vVYqjbJh9Ux3W2D852RF",
          "is_bot": false,
          "headline": "fix(web): resolve Ant nested-label inputs to the correct field",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-10T08:33:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "45517892508feb99953c4609955d62d84d60a980",
          "body": "…t (#235)\n\nBrings a27 runtime up to main and adds the bubblegum.convert package. Engine 0.0.6a27 → 0.0.6a28. Supersedes the a20 converter merge (#234).",
          "is_bot": false,
          "headline": "release: 0.0.6a28 — converter on the a27 runtime; reconcile main drif…",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-10T02:05:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca12ec2b7de5f86f59c49da1257cad2442eed30b",
          "body": "…edes the a20 converter-on-a19 merge (#234)",
          "is_bot": false,
          "headline": "merge main into a28 integration; a28 (a27 runtime + converter) supers…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T13:15:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4af60aa829018b83af625b9330584c8a3548b732",
          "body": "Grafts the additive bubblegum.convert package (17 files) + convert CLI subcommand\n+ [convert] extra onto the a27 runtime branch. No core changes. Bumps a27 → a28.\n\nVerified on the a27 base: 58 converter tests + full suite 1941 passed; a28 wheel\nbuilds with the convert package; generated TypeScript type-checks under tsc --strict.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): manual→automation converter on a27 base; release 0.0.6a28",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T13:14:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bb39b6105920d258222fd7a1138b1c8132b5d446",
          "body": "Adds the `bubblegum convert` command and `bubblegum.convert` package: Excel scenarios → smart-tests TypeScript (flows + tests + data + harness) with project wiring, data extraction, multi-sheet, cleanup, dedup, and validation. Engine 0.0.6a19 → 0.0.6a20.",
          "is_bot": false,
          "headline": "feat(convert): manual test scenario → automation converter (#234)",
          "author_name": "bishnu133",
          "author_login": "bishnu133",
          "committed_at": "2026-07-09T07:28:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7baf94402cc50dd2bc1a7627fe4d99d1d3814c13",
          "body": "Version bump across pyproject.toml, bubblegum/__init__.py, and the package\nmetadata test, and CHANGELOG version header for the `bubblegum convert`\nconverter feature. npm client (@bubblegum-ai/node) unchanged.\n\nDistribution verified: `python -m build` produces bubblegum_ai-0.0.6a20 with the\nfull bubblegum/convert package (17 files) + the convert CLI included.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "release: bump engine to 0.0.6a20 (manual → automation converter)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T07:24:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "be1dc17902323df0a7e9dfb1215d0935bad99334",
          "body": "- convert.cleanup (opt-in): when a scenario creates data ({{... as var}}), the\n  generated test declares cleanupData, imports the configured cleanup function\n  (default ../flows/cleanup.flow with a CleanupData type), calls it in finally,\n  and emits TODO capture lines for each created session variab\n[…]\n no persona/nav\ngaps. 58 convert tests; full suite green (1877 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): cleanup flow wiring + PPH end-to-end example",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T03:31:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "902fda0f8eb4602c0bfc3934dffc735f2fd61165",
          "body": "Extract identical runs of 3+ consecutive step-blocks shared by 3+ scenarios into\nsharedFlowN functions, replacing each occurrence with a call. Off by default\n(output.dedup_subflows / --dedup-subflows).\n\nMatching is on the already-rendered lines, which is what makes it safe next to\ndata extraction: a\n[…]\n under tsc --strict.\n\n56 convert tests; full suite green (1875 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): opt-in sub-flow dedup (§8)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T03:16:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "367e00548c578263d8738f1ee2aa8628e4f76732",
          "body": "…ly, more\n\nImplements the prioritized deferred items from the codegen spec follow-up.\n\n- Data-file extraction (default on): static quoted literals from Enter/Select\n  steps → per-scenario object in <name>.data.ts (camelCase field keys); flows\n  reference them via backtick interpolation and auto-impo\n[…]\ns under tsc --strict. 54 convert tests; full suite green (1873 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): data extraction, multi-sheet, --feature, --validate-on…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T03:12:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a5d74ef5c82a3a7ebb986edf5f3fa9d3a7a46103",
          "body": "Implements the high-value gaps from the code-generator specification so\ngenerated smart-tests are project-wired and runnable, not placeholder stubs.\n\n- convert.imports / convert.personas: generated .test.mts imports the team's\n  real base-URL constant and per-persona credential functions\n  (const cr\n[…]\nsts), docs, example profile, changelog. Full suite green\n(1865 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): project wiring per codegen spec — imports, nav, templates",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-09T02:24:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ab178e2690ce5dbd59f00b2efa6e72b742f8e692",
          "body": "… scenario\n\nPer team feedback: each Excel workbook now generates a single <workbook>.test.mts\ncontaining one test method per scenario row (default group_by=workbook), instead\nof one file per Feature/Epic. Two workbooks in → two test files out, each named\nafter its workbook (override with --name).\n\n-\n[…]\ns), docs, example profile, changelog. Full suite\n  green (1858 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): group by workbook — one test file, one test method per…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-08T09:46:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "43643d744becc9819df79559e2b99011e62703ab",
          "body": "…g sample\n\n- engine.py module docstring showed the pre-pivot features/python/typescript\n  layout with a badge_album example; replaced with the smart-tests layout and a\n  note that filenames derive from each row's Feature/Epic (nothing hardcoded).\n- Genericized example phrases in normalize.py / model\n[…]\n  bill_payment, interest_accrual straight from the Feature/Epic column.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "docs(convert): fix stale docstring + genericize comments + add bankin…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-08T09:21:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "728880dc5cc27b7b1d1b352d45615f63ba81926c",
          "body": "Based on the user's real bubblegum tests, the converter now emits flat\nimperative smart-tests-style TypeScript instead of BDD step definitions.\n\nPer Feature/Epic it generates:\n  - <feature>.flow.ts — one exported async function per scenario, calling the\n    act/verify/observe wrappers; navigation st\n[…]\ndocs, example profile, and changelog.\n  Full suite green (1854 passed).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): pivot default output to smart-tests TypeScript",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-08T08:45:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4c779c4ee8aefabd766dada5d72b1a0ce38baedf",
          "body": "examples/sample_scenarios_template.xlsx is a downloadable, concrete-Gherkin\nsample (with one [Backend] and one deliberately-abstract row) for trying\n`bubblegum convert`. examples/make_sample_scenarios.py regenerates it.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "docs(convert): add ready-to-use sample scenario workbook + generator",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-08T02:38:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "099227c96b75f73fcb1956a9f9f8cbd049651543",
          "body": "Two issues found by running the converter on a real 47-scenario UAT workbook:\n\n- Feature slug collision: two Feature/Epic values differing only by a bracket\n  tag (e.g. [F][BAP] vs [F][Backend] \"... streak mechanics\") slugified\n  identically, so one feature's generated files silently overwrote the o\n[…]\norrectly marked NEEDS_DATA/BACKEND/MANUAL. Added a slug-collision test.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "fix(convert): unique feature slugs + honest step classification",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-08T01:51:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "02a461d853ef89347dc7311ba9361a0f58f76602",
          "body": "Add a `bubblegum convert` command and `bubblegum.convert` package that turn a\nspreadsheet of manually authored Gherkin test scenarios into reviewable\nautomation scaffolds: normalized .feature files, pytest-bdd step definitions\n(Python), and playwright-bdd step definitions (TypeScript) that call Bubb\n[…]\nnthetic fixture (+ generator), and 27 unit/e2e tests. Full suite green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015B8f2aCpNjkaVBEHrkJqHS",
          "is_bot": false,
          "headline": "feat(convert): manual-scenario → automation scaffold converter",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-07T11:09:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2fd5c5b0c492c005cf323893941735f8a2c63f69",
          "body": "…-column rows; release 0.0.6a27\n\n- verify(\"the X page appear\") reduced to searching for that whole sentence and\n  failed. extract_expected now strips a leading article + trailing appearance\n  verbs (appear/appears/loaded/opens/...) and a dangling \"page\", so it checks the\n  visible heading (\"Create B\n[…]\nt_verify_page_and_rows.py. Full unit suite 1879 passed. Version -> a27.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "fix(verify): page-appearance asserts, dynamic tokens in verify, multi…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-05T01:46:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6809fee52e2f8f0e1985588a5c840b3ab6b7b6c4",
          "body": "…6a26\n\nSelecting a radio by label was broken for Ant/MUI radios: the real\n<input type=radio> is hidden (opacity:0) behind a styled wrapper, so name\ngrounding missed it and \"Select X radio\" fell to the dropdown resolver\nwithout actually selecting anything.\n\n- radio_dom resolver: pins the radio's wrap\n[…]\nit/test_radio_fallback.py. Full unit suite 1873 passed. Version -> a26.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "feat(web): radio selection + checked-state verification; release 0.0.…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-04T04:31:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b34e562a8939e4ce8abf5044541ffedb90e8938c",
          "body": "…ues; release 0.0.6a25\n\nTwo additions:\n\n1) Confirmation dialogs. A click/tap now prefers the button inside the topmost\n   open modal. Click \"Submit\" on an Ant \"Submit Badge?\" confirm was resolving to\n   the page's Submit behind the mask and hanging (\"intercepts pointer events\").\n   New pre-grounding\n[…]\nt_dynamic_value_tokens.py. Full unit suite 1864 passed. Version -> a25.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "feat(web): dialog-scoped clicks + named capture/recall of dynamic val…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-04T03:31:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9005c00b5ec967784274e6ddc036b1a097dee9b4",
          "body": "… release 0.0.6a24\n\nEnter \"...\" into Description shown when viewing an Earned Badge was misclassified\nas verify (then failed with \"Unsupported action_type for Playwright execute:\nverify\") because the field label contains \"shown\" — a verify cue word. The cue\nscan ran over the whole instruction includ\n[…]\n_instruction_decompose.py. Full unit suite 1854 passed. Version -> a24.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "fix(parser): leading action verb wins over verify cue in field label;…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-04T03:02:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e2a21f063ecc744aa2bb0f38e05a76fdc977de39",
          "body": "…); release 0.0.6a23\n\nUpload \"<path>\" into <target> could not ground: Ant/MUI Upload widgets hide the\nreal <input type=file> behind a styled button, so the a11y tree and the visible\ninput fallback never see it.\n\nNew pre-grounding resolver file_input_dom pins the file input from the DOM,\nscoring each\n[…]\n unit\nsuite 1852 passed. Version -> 0.0.6a23; documented in USER_GUIDE.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "feat(web): resolve hidden file inputs for upload steps (multi-section…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-04T02:06:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "54e3bb94c514b0d7e01ae4f864c5a0f67c9e20df",
          "body": "…release 0.0.6a22\n\nAnt RangePicker keeps \"active editing\" on one field until Enter is pressed, so a\nbare fill() sent the End value into the Start input — both range values ended up\nin \"Start date\" (06/07/2026 07:0016/07/2026 23:59). Typing into a picker input\nnow activates + commits: click the field\n[…]\n unit suite 1847 passed. Version -> 0.0.6a22; documented in USER_GUIDE.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "fix(web): commit typed value into date/time picker inputs via Enter; …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-04T01:47:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ea60ce94ea4f30b17963a9657b4ec6e92510e6aa",
          "body": "…ease 0.0.6a21\n\n\"type into Start date / End date\" targeted a nameless Ant RangePicker input\n(no id/label/aria — only a date-range attribute or Start/End placeholder), so\nname-based grounding could mis-hit another \"date\"-ish element on the page and\nthe value landed in the wrong field.\n\nNew pre-ground\n[…]\n unit suite 1844 passed.\nVersion -> 0.0.6a21; documented in USER_GUIDE.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "fix(web): deterministic resolver for date-range picker start/end; rel…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-03T13:43:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5a415a1adf9ab16e44ab0da5e848323da45d38cf",
          "body": "…0.0.6a20\n\nReconciles two divergent lines that both left PyPI incomplete:\n  * main a17->a19: web clickable-fallback fix (strips trailing widget nouns),\n    but WITHOUT the a18 dynamic-value tokens.\n  * this branch a17->a18: {{timestamp}}/{{uuid}}/{{random}} tokens + docs,\n    never merged to main.\nS\n[…]\nPESCRIPT, and the Node\nREADME. Version guard + __version__ -> 0.0.6a20.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "Merge main (a19) into token branch; add @time absolute-time; release …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-03T10:45:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e8b288650b1db0af09983ede682099c6d32d15c2",
          "body": "…0.6a19\n\n\"Click the <X> menu/button/link/tab/option/item/field\" now resolves the control\nnamed <X> via the DOM clickable fallback by retrying with the trailing widget\nword removed (e.g. \"Badges menu\" -> the \"Badges\" nav item). No parser change, so\n\"X menu\" target phrases are preserved. a18 on PyPI w\n[…]\nis repo's\nmain; this is the next release after a17. Engine -> 0.0.6a19.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(web): clickable fallback strips trailing widget nouns; release 0.…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-03T09:50:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "87158eb2593d9305670a308d63083b763e4ca75c",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "test: bump version guard to 0.0.6a18",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-03T09:04:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d8124e2bb6d25ff8489d9d63e2a67374c43d996d",
          "body": "Add a \"Dynamic values\" section to docs/USER_GUIDE.md and\ndocs/HOW_TO_USE_TYPESCRIPT.md covering both the relative date/time tokens\nand the new uniqueness tokens ({{timestamp}}, {{uuid}}, {{random}}), with a\nnote on reading the generated value back. Fills a gap: the date tokens were\npreviously documented only in the Node client README.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "docs: document dynamic-value tokens (dates/times + uniqueness)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-03T09:03:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "09154abed0027d918394d6d7531594dcc1499f15",
          "body": "…dom}})\n\nExtend the dynamic-value token grammar beyond relative dates so any field\nthat needs a value computed at run time — a badge name, an email, any\ncreate-form field with a unique constraint — can be parameterised inline\ninstead of hard-coded:\n\n  - {{timestamp}}  epoch seconds; :ms for millis; \n[…]\nnt both token families\nin the Node README. Engine 0.0.6a17 -> 0.0.6a18.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pm2yrGhUZmxXhLvaChJbYL",
          "is_bot": false,
          "headline": "feat: uniqueness dynamic-value tokens ({{timestamp}}, {{uuid}}, {{ran…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-03T08:54:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d1b57772c2dc7bfe48b5f6851597502eb29fd36e",
          "body": "type/enter into a field with no accessible name (e.g. a <textarea> whose\n<label for=...> points at a missing id — the H365 Remarks field) now resolves\nvia a DOM fallback scoring visible enabled inputs/textareas by label /\nplaceholder / nearby form-item label. Excludes ant-select search inputs and\ndisabled fields. Engine -> 0.0.6a17.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(web): DOM input fallback for nameless text fields; release 0.0.6a17",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-23T03:52:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5472d66b91085345e8e8017a492a481d5f747778",
          "body": "…de 0.0.6-alpha.5\n\nAdds bg.preflight(steps[]) — dry-runs each step against the current page and\nreports ok/status/confidence/resolver/error without executing, so a page's\nsteps can be validated in one batch instead of one run at a time. Engine\nunchanged (0.0.6a16); client -> 0.0.6-alpha.5.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "feat(node): preflight() for batch script validation; @bubblegum-ai/no…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-23T03:38:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ed6ed118e42297f7fb53b475b4b9ea8bffe9c466",
          "body": "When a click can't be ground to a unique element (Ant renders two equal\nrole=button candidates for one labelled button), act() now falls back to a DOM\nresolver finding the single interactive element by accessible name + role,\ncollapsing nested matches to the outermost interactive ancestor. Same pattern\nas the select/link/table-cell fallbacks. Engine -> 0.0.6a16.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(web): DOM clickable fallback for ambiguous clicks; release 0.0.6a16",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-22T16:48:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "130b1534e2dbbef9708a020b6b483f33f37f8182",
          "body": "…; release 0.0.6a15\n\nA click on a control wrapping a same-text node (<button><span>Update account\nstatus</span></button>) raised a 0.00-gap AmbiguousTargetError. On a confidence\ntie the engine now prefers the candidate whose role best fits the action\n(button/link/option over a non-interactive text t\n[…]\n stay\ndistinct so real ambiguity is still surfaced. Engine -> 0.0.6a15.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(grounding): role-aware tie-break for clicks (button vs text twin)…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-22T16:39:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8990e8e5942c8da03f1b6b53dabb47815fad3499",
          "body": "…ase 0.0.6a14\n\nverify now treats quoted text as the literal assertion target, so\nverify('... an \"Update account status\" button') checks \"Update account status\"\nand verify('account status is \"Active\"') checks \"Active\", rather than failing\non the whole sentence. Multiple quoted phrases must all be vis\n[…]\nverifies and explicit expected_value are unchanged. Engine -> 0.0.6a14.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(web): verify checks quoted text inside a descriptive phrase; rele…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-22T16:02:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a5adb5234731784e280165ea2e9c5e4cb009540c",
          "body": "… 0.0.6a13\n\nAdds two deterministic click features for elements whose visible text is\ndynamic. (1) Table coordinates: \"under the PPHID column click the 1st row\nvalue\" / \"Click the PPHID link in the first result row\" / row_match by another\ncolumn; resolves Ant/native/ARIA tables, the column by header,\n[…]\n365\ntable DOM. Engine -> 0.0.6a13; @bubblegum-ai/node -> 0.0.6-alpha.4.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "feat(web): click by table cell (column+row) and by link text; release…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-18T15:13:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "95a4ae7ad9ac8b23676b54d6bf02d21b83e6a117",
          "body": "…se 0.0.6a12\n\nWhen the a11y snapshot can't ground a unique combobox (several nameless\ncomboboxes on the page), act() now falls back to a DOM-based select-trigger\nresolver that scores every visible select by associated label (strongest),\nplaceholder, displayed value, and text against the step's targe\n[…]\nng validated against the real\ncaptured H365 markup. Engine -> 0.0.6a12.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(web): DOM fallback disambiguates multiple nameless selects; relea…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-18T11:42:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "22f0a4696f68acffd20b12b349571fc8ac53dc7b",
          "body": "…e 0.0.6a11\n\n\"Select X from the Y dropdown\" could flake between resolving (~0.72) and a\nLowConfidence failure (~0.57) depending on whether the combobox was exposed as\nnameless or with its value as the accessible name. For dropdown/select intents\nthe engine now accepts the best combobox/listbox candi\n[…]\ns still fail safely. Clearer LowConfidence\nmessage. Engine -> 0.0.6a11.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "fix(grounding): reliably resolve nameless/value-named selects; releas…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-18T11:30:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cd08ba4affed916f5d8d1a56850fc5864ab3f77d",
          "body": "….0.6a10\n\nAdds page-scoped table verification to verify(): assert a table's columns\nexist, and assert a value under a column for a row matched by another column\n(DB-style key). Structured (assertion_type=\"table\" with columns/row_match/cell)\nand natural-language forms (\"the table has columns A, B\", '\n[…]\nured H365 DOM. Engine ->\n0.0.6a10; @bubblegum-ai/node -> 0.0.6-alpha.3.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VnikFEuRcyen84Pj6SzYyt",
          "is_bot": false,
          "headline": "feat(web): table assertions (columns + cell values by row); release 0…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-06-18T08:53:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 6,
      "commits_last_year": 375,
      "latest_release_at": "2026-06-16T03:45:59Z",
      "latest_release_tag": "v0.0.6-alpha",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 12,
      "days_since_latest_release": 41,
      "mean_days_between_releases": 8.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 28,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "bubblegum-ai",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "Development Status :: 3 - Alpha",
            "Intended Audience :: Developers",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Topic :: Software Development :: Testing"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/bubblegum-ai/",
          "is_deprecated": false,
          "latest_version": "0.0.6a61",
          "repository_url": "https://github.com/bishnu133/bubblegum",
          "versions_count": 61,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-06-15T13:50:23.887339Z",
          "latest_published_at": "2026-07-28T03:41:43.611879Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "clients/node/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 160075,
      "source_files_sampled": 425,
      "oversized_source_files": 6,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "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": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "pydantic",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.0"
        },
        {
          "name": "pyyaml",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        }
      ],
      "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": 2,
        "merged_prs": 244,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "bishnu133",
          "commits": 245,
          "avatar_url": "https://avatars.githubusercontent.com/u/188071550?v=4"
        },
        {
          "type": "User",
          "login": "claude",
          "commits": 128,
          "avatar_url": "https://avatars.githubusercontent.com/u/81847?v=4"
        },
        {
          "type": "User",
          "login": "bishnuprasadp-tw",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/106137421?v=4"
        }
      ],
      "contributors_sampled": 3,
      "top_contributor_share": 0.65
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "node-client.yml",
        "npm-publish.yml",
        "publish-check.yml",
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 7,
            "reason": "8 out of 11 merged PRs checked by a CI test -- score normalized to 7",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/11 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 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 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 1,
            "reason": "dependency not pinned by hash detected -- score normalized to 1",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 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": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "3d182208e550227f614f9102febab019c5d78b3a",
        "ran_at": "2026-07-28T03:42:59Z",
        "aggregate_score": 4.4,
        "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-28T03:41:46Z",
      "oldest_open_prs": [
        {
          "number": 102,
          "created_at": "2026-05-12T13:48:09Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 207,
          "created_at": "2026-05-20T09:26:55Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-28T03:40:48Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/bishnu133/bubblegum",
    "host": "github.com",
    "name": "bubblegum",
    "owner": "bishnu133"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 54,
      "inputs": {
        "security": 44,
        "vitality": 83,
        "community": 24,
        "governance": 51,
        "engineering": 63
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 83,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "commits_last_year": 375,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 12
            },
            "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": "12/52 weeks with commits",
                "points": 8.3,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 12
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "375 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 375
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 6,
              "latest_release_tag": "v0.0.6-alpha",
              "releases_from_tags": false,
              "days_since_latest_release": 41,
              "mean_days_between_releases": 8.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "6 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 41 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 41
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~8.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 8.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 24,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 51,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 24,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 3,
              "top_contributor_share": 0.65
            },
            "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 65% of commits",
                "points": 7.9,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 65
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "3 contributors",
                "points": 4.1,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 72,
            "inputs": {
              "merged_prs": 244,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "244/244 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 244,
                      "decided": 244
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/11 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "critical",
            "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": 24,
            "inputs": {
              "followers": 0,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "bishnu133",
              "public_repos": 5,
              "account_age_days": 623
            },
            "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": "0 followers of bishnu133",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "bishnu133"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "5 public repos, account ~1 yr old",
                "points": 9.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 5
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 1
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "bubblegum-ai"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "61 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 61
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 63,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 62,
            "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": "8 out of 11 merged PRs checked by a CI test -- score normalized to 7",
                "points": 14,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": 44,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 44,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4.4
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "8 out of 11 merged PRs checked by a CI test -- score normalized to 7",
                "points": 1.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/11 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no 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 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 0.5,
                "status": "partial",
                "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": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 52,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.9,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "90 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 90,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "clients/node/tsconfig.json"
              ],
              "agent_commit_share": 0.77,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "clients/node/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "clients/node/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "77 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 77,
                      "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 1",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 160075,
              "source_files_sampled": 425,
              "oversized_source_files": 6
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (clients/node/tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "clients/node/tsconfig.json",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "6/425 source files over 60KB",
                "points": 54.2,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 425,
                      "oversized": 6
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:bubblegum-ai@0.0.6a61; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T03:43:15.340355Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/b/bishnu133/bubblegum.svg",
  "full_name": "bishnu133/bubblegum",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Оцінки — це сигнали, а не гарантії. Вони відображають публічно видимі практики на GitHub — це не аудит коду й не гарантія безпеки.

Відсутні дані виключаються, а ваги перенормовуються — нуль за відсутність ніколи не ставиться. Методологія версіонована й відкрита: метрики v1.13.0, схема v0.27.0 — повна методологія · вікі метрик.

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