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

ably / ably-java

Java, Android, Clojure and Scala client library SDK for Ably realtime messaging service

Java · KotlinApache-2.0★ 100 зірок⑂ 45 форківз груд. 2014 р.Переглянути на GitHub ↗

ably/ably-java має індекс здоров’я 74 зі 100, що відповідає смузі «Добрий». Найвищий показник — Vitality (94/100), найнижчий — AI Readiness (58/100). Останнє оновлення було 4 дні тому. Більшість нещодавньої роботи виконують 3 учасники.

74
загалом / 100
Добрий

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

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

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

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

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

Власність

214 підписників123 публічні репозиторіїз черв. 2012 р.

За цим репозиторієм стоїть організація — спільна, підзвітна опіка, здатна пережити будь-якого окремого мейнтейнера.

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

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

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

94Відмінний · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 4 дн. тому
26.3/36Ритм комітів — 38/52 тижнів із комітами
18/18Обсяг комітів — 280 комітів за останній рік
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Використані вхідні дані
commits_last_year280
human_commit_share1
days_since_last_push4
active_weeks_last_year38
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 100 релізів
36/36Свіжість релізів — останній реліз 12 дн. тому
27/27Ритм релізів — реліз кожні ~32,1 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count100
latest_release_tagv1.8.0
releases_from_tagsні
days_since_latest_release12
mean_days_between_releases32,1
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

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

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

61Помірний · 18% загального індексу
Як обчислюється оцінка
32.4/60Зірки — 100 зірок
13.7/25Форки — 45 форків
8.4/15Спостерігачі — 34 спостерігачів
Використані вхідні дані
forks45
stars100
watchers34
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (Apache-2.0)
18/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ні

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

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

75Добрий · 24% загального індексу
Як обчислюється оцінка
36/54Бас-фактор — на 3 контриб’ютор(ів) припадає половина всіх комітів
17.1/22.5Розподіл комітів — головний контриб’ютор — автор 24% комітів
13.5/13.5Широта контриб’юторів — 38 контриб’юторів
10/10OpenSSF Scorecard: Contributors — project has 27 contributing companies or organizations
Використані вхідні дані
bus_factor3
contributors_sampled38
top_contributor_share0,242
Як обчислюється оцінка
34.9/46.8Вирішення issue — закрито 75% issue
31.5/38.3Прийняття PR — злито 571/693 вирішених PR
10.5/15OpenSSF Scorecard: Code-Review — Found 5/7 approved changesets -- score normalized to 7
Використані вхідні дані
merged_prs571
open_issues134
closed_issues395
issue_closed_ratio0,747
closed_unmerged_prs122
Як обчислюється оцінка
30/30Підтримка власника — у власності організації
0/20Верифікований домен
16.8/25Охоплення власника — 214 підписників у ably
25/25Послужний список — 123 публічних репозиторіїв, вік облікового запису ~14 р.
Використані вхідні дані
followers214
owner_typeOrganization
is_verified
owner_loginably
public_repos123
account_age_days5 151

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

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

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

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

65Помірний
Як обчислюється оцінка
30/30README
0/25Каталог документації
15/15Сайт документації / домашня сторінка — https://ably.com/download
10/10Опис репозиторію
10/10Теми — 9 тем
0/10Wiki
Використані вхідні дані
topicsjava, android, realtime-messaging, client-library, rest, realtime, clojure, scala, sdk
has_wikiні
homepagehttps://ably.com/download
has_readmeтак
has_docs_dirні
has_descriptionтак

Безпека

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

66Помірний · 16% загального індексу

Стан безпеки

66Помірний
Як обчислюється оцінка
6.8/7.5Binary-Artifacts — binaries present in source code
0/7.5Branch-Protection — немає даних
2.5/2.5CI-Tests — 7 out of 7 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
5.2/7.5Code-Review — Found 5/7 approved changesets -- score normalized to 7
2.5/2.5Contributors — project has 27 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
5/5Pinned-Dependencies — all dependencies are pinned
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 — немає даних
4.5/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate6,6
Виключено з оцінювання (немає даних або не застосовно): branch_protection, signed_releases. Залишкові ваги перенормовано.

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

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

58Помірний · 0% загального індексу
Як обчислюється оцінка
0/45Інструкції для агентів — немає CLAUDE.md / AGENTS.md / правил редактора
0/15Машиночитана документація (llms.txt)
34.7/40Читабельна історія комітів — намір зазначено у 65 з 100 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,65
agent_instruction_files
agent_instruction_max_bytes
Як обчислюється оцінка
12.6/18Розгортання однією командою — android/build.gradle.kts, build.gradle.kts, examples/build.gradle.kts (домовленість інструментарію, без раннера задач)
22/22Автоматизовані тести
0/11Конфігурація лінтера / форматера
11/11Статична перевірка типів — Java (статично типізована)
0/10Відтворюване середовище
10/10Підтверджена практика роботи з агентами — 8 з останніх 100 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Використані вхідні дані
has_nixні
has_testsтак
lockfiles
has_dockerfileні
typed_languageтак
bootstrap_files
has_devcontainerні
has_linter_configні
typecheck_configs
agent_commit_share0,08
toolchain_manifestsandroid/build.gradle.kts, build.gradle.kts, examples/build.gradle.kts, gradle-lint/build.gradle, java/build.gradle.kts, liveobjects/build.gradle.kts, network-client-core/build.gradle.kts, network-client-default/build.gradle.kts, network-client-okhttp/build.gradle.kts, pubsub-adapter/build.gradle.kts, uts/build.gradle.kts
dependency_bot_commit_share0
Як обчислюється оцінка
45/45Типізований код — Java (статично типізована)
54/55Керовані розміри файлів — 8/456 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languageJava
largest_source_bytes161 962
source_files_sampled456
oversized_source_files8
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
0/20Сервер MCP
40/40Придатні до запуску приклади — example, examples
Використані вхідні дані
example_dirsexample, examples
has_mcp_signalні
api_schema_files

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

100зірок GitHub
38контриб'юторів
280комітів за останні 12 місяців
4днів від останнього пушу
100релізів
3бас-фактор
134відкритих issue
Mavenпакетних екосистем

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

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token

Докладніше

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

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

010203040504522015-082021-012026-07
Мажорні 1Мінорні 7Патчі 87

Кожна точка охоплює 10 днів.

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

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

9Binary-Artifactsbinaries present in source code
н/дBranch-Protectioninternal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
10CI-Tests7 out of 7 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
7Code-ReviewFound 5/7 approved changesets -- score normalized to 7
10Contributorsproject has 27 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
10Pinned-Dependenciesall dependencies are pinned
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
н/дSigned-Releasesno releases found
6Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Усі залежності 0

Повний розв'язаний набір залежностей із графа залежностей GitHub: 0 прямих і 0 непрямих (транзитивних) пакетів. Транзитивне замикання є повним, коли в репозиторії закомічено lockfile.

РеєстрПакетВерсіяЗв'язок
Сповіщення про залежності не оцінено

Звірка сповіщень не відбулася для цього звіту: No resolved dependencies to assess

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [
        "java",
        "android",
        "realtime-messaging",
        "client-library",
        "rest",
        "realtime",
        "clojure",
        "scala",
        "sdk"
      ],
      "is_fork": false,
      "size_kb": 11909,
      "has_wiki": false,
      "homepage": "https://ably.com/download",
      "languages": {
        "HTML": 1161,
        "Java": 2581498,
        "Shell": 2346,
        "Groovy": 753,
        "Kotlin": 700905,
        "Python": 17578,
        "JavaScript": 178
      },
      "pushed_at": "2026-07-21T12:26:16Z",
      "created_at": "2014-12-01T11:54:06Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-20T11:23:28Z",
      "description": "Java, Android, Clojure and Scala client library SDK for Ably realtime messaging service",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Java",
      "significant_languages": [
        "Java",
        "Kotlin"
      ]
    },
    "owner": {
      "blog": "https://ably.com/documentation",
      "name": "Ably Realtime - our client library SDKs and libraries",
      "type": "Organization",
      "login": "ably",
      "company": null,
      "location": "London, UK",
      "followers": 214,
      "avatar_url": "https://avatars.githubusercontent.com/u/1859245?v=4",
      "created_at": "2012-06-17T17:14:20Z",
      "is_verified": null,
      "public_repos": 123,
      "account_age_days": 5151
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.8.0",
          "kind": "minor",
          "published_at": "2026-07-13T17:33:16Z"
        },
        {
          "tag": "v1.7.2",
          "kind": "patch",
          "published_at": "2026-05-05T12:04:25Z"
        },
        {
          "tag": "v1.7.1",
          "kind": "patch",
          "published_at": "2026-03-26T17:09:57Z"
        },
        {
          "tag": "v1.7.0",
          "kind": "minor",
          "published_at": "2026-03-18T11:55:41Z"
        },
        {
          "tag": "v1.6.1",
          "kind": "patch",
          "published_at": "2026-01-28T20:18:52Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2026-01-21T11:39:48Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2025-11-28T11:13:31Z"
        },
        {
          "tag": "v1.4.2",
          "kind": "patch",
          "published_at": "2025-10-30T14:43:21Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2025-10-22T13:02:59Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2025-09-27T10:53:17Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2025-08-28T12:18:34Z"
        },
        {
          "tag": "v1.2.54",
          "kind": "patch",
          "published_at": "2025-07-18T15:13:50Z"
        },
        {
          "tag": "v1.2.53",
          "kind": "patch",
          "published_at": "2025-06-17T13:37:06Z"
        },
        {
          "tag": "v1.2.52",
          "kind": "patch",
          "published_at": "2025-04-01T12:07:33Z"
        },
        {
          "tag": "v1.2.51",
          "kind": "patch",
          "published_at": "2025-03-18T11:09:37Z"
        },
        {
          "tag": "v1.2.50",
          "kind": "patch",
          "published_at": "2025-02-25T12:08:25Z"
        },
        {
          "tag": "v1.2.49",
          "kind": "patch",
          "published_at": "2025-02-10T13:22:58Z"
        },
        {
          "tag": "v1.2.48",
          "kind": "patch",
          "published_at": "2025-01-13T17:41:19Z"
        },
        {
          "tag": "v1.2.47",
          "kind": "patch",
          "published_at": "2024-12-11T11:52:12Z"
        },
        {
          "tag": "v1.2.46",
          "kind": "patch",
          "published_at": "2024-11-29T09:23:10Z"
        },
        {
          "tag": "v1.2.45",
          "kind": "patch",
          "published_at": "2024-11-21T12:43:42Z"
        },
        {
          "tag": "v1.2.44",
          "kind": "patch",
          "published_at": "2024-10-18T14:01:16Z"
        },
        {
          "tag": "v1.2.43",
          "kind": "patch",
          "published_at": "2024-10-08T09:08:46Z"
        },
        {
          "tag": "v1.2.42",
          "kind": "patch",
          "published_at": "2024-09-18T17:53:44Z"
        },
        {
          "tag": "v1.2.41",
          "kind": "patch",
          "published_at": "2024-07-19T09:45:40Z"
        },
        {
          "tag": "v1.2.40",
          "kind": "patch",
          "published_at": "2024-06-21T08:04:50Z"
        },
        {
          "tag": "v1.2.39",
          "kind": "patch",
          "published_at": "2024-06-03T16:28:13Z"
        },
        {
          "tag": "v1.2.38",
          "kind": "patch",
          "published_at": "2024-05-14T08:23:35Z"
        },
        {
          "tag": "v1.2.37",
          "kind": "patch",
          "published_at": "2024-04-10T09:14:17Z"
        },
        {
          "tag": "v1.2.36",
          "kind": "patch",
          "published_at": "2024-04-04T08:49:08Z"
        },
        {
          "tag": "v1.2.35",
          "kind": "patch",
          "published_at": "2024-03-04T21:20:53Z"
        },
        {
          "tag": "v1.2.34",
          "kind": "patch",
          "published_at": "2024-02-27T13:45:46Z"
        },
        {
          "tag": "v1.2.33",
          "kind": "patch",
          "published_at": "2023-11-24T16:25:31Z"
        },
        {
          "tag": "v1.2.32",
          "kind": "patch",
          "published_at": "2023-09-29T18:04:36Z"
        },
        {
          "tag": "v1.2.31",
          "kind": "patch",
          "published_at": "2023-07-06T15:14:25Z"
        },
        {
          "tag": "v1.2.30",
          "kind": "patch",
          "published_at": "2023-06-07T13:43:03Z"
        },
        {
          "tag": "v1.2.29",
          "kind": "patch",
          "published_at": "2023-05-17T11:35:25Z"
        },
        {
          "tag": "v1.2.28",
          "kind": "patch",
          "published_at": "2023-05-05T10:48:39Z"
        },
        {
          "tag": "v1.2.27",
          "kind": "patch",
          "published_at": "2023-03-27T15:56:57Z"
        },
        {
          "tag": "v1.2.26",
          "kind": "patch",
          "published_at": "2023-02-28T10:20:25Z"
        },
        {
          "tag": "v1.2.25",
          "kind": "patch",
          "published_at": "2023-02-07T14:36:59Z"
        },
        {
          "tag": "v1.2.24",
          "kind": "patch",
          "published_at": "2023-02-02T11:56:13Z"
        },
        {
          "tag": "v1.2.23",
          "kind": "patch",
          "published_at": "2023-01-25T18:48:42Z"
        },
        {
          "tag": "v1.2.22",
          "kind": "patch",
          "published_at": "2023-01-05T10:36:58Z"
        },
        {
          "tag": "v1.2.21",
          "kind": "patch",
          "published_at": "2022-12-12T10:56:28Z"
        },
        {
          "tag": "v1.2.20",
          "kind": "patch",
          "published_at": "2022-11-24T14:25:26Z"
        },
        {
          "tag": "v1.2.19",
          "kind": "patch",
          "published_at": "2022-11-23T16:48:19Z"
        },
        {
          "tag": "v1.2.18",
          "kind": "patch",
          "published_at": "2022-09-23T16:08:26Z"
        },
        {
          "tag": "v1.2.17",
          "kind": "patch",
          "published_at": "2022-09-20T14:46:21Z"
        },
        {
          "tag": "v1.2.16",
          "kind": "patch",
          "published_at": "2022-07-19T13:43:06Z"
        },
        {
          "tag": "v1.2.15",
          "kind": "patch",
          "published_at": "2022-07-11T17:22:01Z"
        },
        {
          "tag": "v1.2.14",
          "kind": "patch",
          "published_at": "2022-06-23T08:25:00Z"
        },
        {
          "tag": "v1.2.13",
          "kind": "patch",
          "published_at": "2022-06-16T14:35:47Z"
        },
        {
          "tag": "v1.2.12",
          "kind": "patch",
          "published_at": "2022-05-05T11:14:20Z"
        },
        {
          "tag": "v1.2.11",
          "kind": "patch",
          "published_at": "2022-02-04T11:32:01Z"
        },
        {
          "tag": "v1.2.10",
          "kind": "patch",
          "published_at": "2021-09-30T10:26:46Z"
        },
        {
          "tag": "v1.2.9",
          "kind": "patch",
          "published_at": "2021-09-13T13:53:58Z"
        },
        {
          "tag": "v1.2.8",
          "kind": "patch",
          "published_at": "2021-09-01T06:48:21Z"
        },
        {
          "tag": "v1.2.7",
          "kind": "patch",
          "published_at": "2021-08-05T13:34:47Z"
        },
        {
          "tag": "v1.2.6",
          "kind": "patch",
          "published_at": "2021-05-12T16:51:40Z"
        },
        {
          "tag": "v1.2.5",
          "kind": "patch",
          "published_at": "2021-03-04T10:24:07Z"
        },
        {
          "tag": "v1.2.4",
          "kind": "patch",
          "published_at": "2021-03-02T13:40:29Z"
        },
        {
          "tag": "v1.2.3",
          "kind": "patch",
          "published_at": "2020-11-23T12:41:44Z"
        },
        {
          "tag": "v1.2.2",
          "kind": "patch",
          "published_at": "2020-09-17T10:39:45Z"
        },
        {
          "tag": "v1.2.1",
          "kind": "patch",
          "published_at": "2020-06-15T17:49:53Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2020-06-08T11:38:07Z"
        },
        {
          "tag": "v1.1.11",
          "kind": "patch",
          "published_at": "2020-05-19T08:26:08Z"
        },
        {
          "tag": "v1.1.10",
          "kind": "patch",
          "published_at": "2020-03-04T20:21:27Z"
        },
        {
          "tag": "v1.1.9",
          "kind": "patch",
          "published_at": "2020-03-03T13:58:58Z"
        },
        {
          "tag": "v1.1.8",
          "kind": "patch",
          "published_at": "2020-03-03T14:01:12Z"
        },
        {
          "tag": "v1.1.8-RC1",
          "kind": "prerelease",
          "published_at": "2019-12-17T12:22:08Z"
        },
        {
          "tag": "v1.1.7",
          "kind": "patch",
          "published_at": "2019-12-04T11:31:31Z"
        },
        {
          "tag": "v1.1.6",
          "kind": "patch",
          "published_at": "2019-11-15T23:34:51Z"
        },
        {
          "tag": "v1.1.5",
          "kind": "patch",
          "published_at": "2019-10-17T12:39:14Z"
        },
        {
          "tag": "v1.1.4",
          "kind": "patch",
          "published_at": "2019-10-12T23:20:29Z"
        },
        {
          "tag": "v1.1.3",
          "kind": "patch",
          "published_at": "2019-07-20T23:21:59Z"
        },
        {
          "tag": "v1.1.2",
          "kind": "patch",
          "published_at": "2019-07-11T17:07:47Z"
        },
        {
          "tag": "v1.0.14",
          "kind": "patch",
          "published_at": "2019-04-24T09:49:31Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2019-04-10T21:54:08Z"
        },
        {
          "tag": "v1.0.13",
          "kind": "patch",
          "published_at": "2019-04-10T21:18:56Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2019-02-13T16:59:39Z"
        },
        {
          "tag": "v1.0.12",
          "kind": "patch",
          "published_at": "2019-02-13T16:21:00Z"
        },
        {
          "tag": "v1.0.11",
          "kind": "patch",
          "published_at": "2019-01-17T11:34:17Z"
        },
        {
          "tag": "v1.1.0-RC1",
          "kind": "prerelease",
          "published_at": "2018-12-13T09:56:29Z"
        },
        {
          "tag": "v1.0.10",
          "kind": "patch",
          "published_at": "2018-12-13T06:47:16Z"
        },
        {
          "tag": "v1.0.9",
          "kind": "patch",
          "published_at": "2018-12-11T18:52:18Z"
        },
        {
          "tag": "v1.0.8",
          "kind": "patch",
          "published_at": "2018-11-03T00:45:33Z"
        },
        {
          "tag": "v1.0.7",
          "kind": "patch",
          "published_at": "2018-08-17T06:05:29Z"
        },
        {
          "tag": "v1.0.6",
          "kind": "patch",
          "published_at": "2018-07-25T12:11:38Z"
        },
        {
          "tag": "v1.0.5",
          "kind": "patch",
          "published_at": "2018-07-17T22:45:04Z"
        },
        {
          "tag": "v1.0.4",
          "kind": "patch",
          "published_at": "2018-06-22T16:25:09Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2018-05-18T16:25:20Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2018-03-01T19:33:29Z"
        },
        {
          "tag": "v1.1.0-beta.push.1",
          "kind": "prerelease",
          "published_at": "2017-10-13T16:09:33Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2017-10-13T15:39:01Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2017-10-13T15:19:23Z"
        },
        {
          "tag": "v0.9.0beta1",
          "kind": "other",
          "published_at": "2017-03-07T01:38:14Z"
        },
        {
          "tag": "v0.8.4",
          "kind": "patch",
          "published_at": "2016-10-07T11:38:02Z"
        },
        {
          "tag": "v0.8.3",
          "kind": "patch",
          "published_at": "2016-08-25T08:03:17Z"
        },
        {
          "tag": "v0.8.2",
          "kind": "patch",
          "published_at": "2016-03-14T13:51:58Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "74d267f1503e29022beb952a76deb0e5faeb9fa0",
          "body": "Release/1.8.0",
          "is_bot": false,
          "headline": "Merge pull request #1227 from ably/release/1.8.0",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T17:29:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e669794a4319454311e6f8c90ead5be8fb2051f",
          "body": null,
          "is_bot": false,
          "headline": "Update CHANGELOG for 1.8.0",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T12:25:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44664b40c38d4c10787fae4166c48a9716e3ca88",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 1.8.0",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T10:07:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b03edbf44b4ab24ac32ec67864e2f8952a583b8b",
          "body": "…lementation\n\n[Feature] Path based LiveObjects Implementation",
          "is_bot": false,
          "headline": "Merge pull request #1214 from ably/feature/path-based-liveobjects-imp…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T09:57:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a44020d49ff53121449f410db35d4ea15946e8bd",
          "body": "…overhead\n\nof updating the same, going forward it's better to grab context from README.md\nor generate `index.html` doc file from `README.md`",
          "is_bot": false,
          "headline": "Removed index.html since it's no longer needed and there's recurring …",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T09:26:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4edf612a4245dbafe06205fed9b2ab1f39b8e50",
          "body": "[AIT-1103] fix(liveobjects): Fix UTS unit tests",
          "is_bot": false,
          "headline": "Merge pull request #1226 from ably/fix/liveobjects-failing-uts-tests",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T09:16:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce72a7da23f38642113a2d68ba952b3e908562de",
          "body": "…in-implementation\n\n[AIT-1019] feat(liveobjects): implement remaining path-based API — parent references, event bubbling etc",
          "is_bot": false,
          "headline": "Merge pull request #1224 from ably/feature/liveobjects-remaining-kotl…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T09:10:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5934d804bef63f34a8f911d5ff0a02233689146a",
          "body": "fix(uts): wait for outbound publish before injecting ACK in RTO20 test\n\nThe ack-after-echo test raced: increment() dispatches its publish on\nsequentialScope, so the manually injected ACK for msgSerial 0 could\nreach ConnectionManager before the publish was pending, where\nPendingMessages.ack discards it - incFuture never completed and the\ntest hung with UncompletedCoroutinesError (flaky on CI, e.g. runs\n29081250922 and 29236093941).",
          "is_bot": false,
          "headline": "docs(uts): hyphenate 'no-ops' in deviations heading",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T09:10:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "30c1821c18f0ccca5d18c851938b00ff623857a2",
          "body": null,
          "is_bot": false,
          "headline": "Updated private deviations for latest UTS spec generated unit tests",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T08:37:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32f928cefa26b6d9f952f112fc1a3826ee56b8ec",
          "body": "…nd sending data",
          "is_bot": false,
          "headline": "Added appropriate comments for use of sequentialScope for accessing a…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T08:36:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c91cf74b9891d5ed8567b83004223b2b4768542",
          "body": "…r spec RTPO8f",
          "is_bot": false,
          "headline": "Updated PathObject#Instance to return instance for primitive types fo…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-13T08:34:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6c2b27fedf527955974915fd2e5a9a46e6309118",
          "body": "…Serial; doc typo\n\n- objectsClient emitted ATTACHED with the caller's attachedSerial but\n  always followed with an OBJECT_SYNC for \"sync1:\"; a caller overriding\n  the serial (e.g. \"sync2:cursor\") would get mismatched sync ids that\n  register as a second new sync (RTO5a2). The sync id is now derived\n\n[…]\nfrom attachedSerial. No current caller hits the mismatch — latent\n  footgun only; all 183 liveobjects UTS tests unchanged and green.\n- Fix the dangling \";.\" in throwIfMissingObjectSubscribeMode's doc.",
          "is_bot": false,
          "headline": "fix(uts): address review — derive objectsClient sync id from attached…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-10T10:26:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f73a412434eca869bc438ce31318d2ad9004d5f6",
          "body": "…ync waiters (RTO20e/e1)\n\nTwo genuine spec-compliance bugs surfaced by cross-checking the UTS unit\nsuite against ably-js (the reference implementation) — both confirmed at\nsource level against objects-features.md, with ably-js compliant on each.\n\nRTO23e — get() threw 90001 on a DETACHED channel inst\n[…]\n id and spec point against the suite (audited programmatically).\n\nVerified: :uts:runUtsUnitTests liveobjects 183/0, runLiveObjectUnitTests\ngreen, checkWithCodenarc/checkstyleMain/checkstyleTest clean.",
          "is_bot": false,
          "headline": "fix(liveobjects): get() re-attaches DETACHED (RTO23e); event-driven s…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-10T08:58:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0f0075a0cd64f32a64df60db25e940f8d4c408c7",
          "body": "getOrPut on a ConcurrentHashMap may invoke its factory on a losing thread during a\nconcurrent first-time getInstance, constructing a duplicate DefaultRealtimeObject whose\ninit-started coroutine would then leak. computeIfAbsent runs the factory at most once per\nchannel, so exactly one instance is created. It needs Java 8 / Android API 24, already\nrequired by this module's CompletableFuture-based public API.",
          "is_bot": false,
          "headline": "fix(liveobjects): use computeIfAbsent for RealtimeObject caching",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T12:00:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ea697c24192447a8eda67c9feda8923ba0a9924",
          "body": "…ntation\n\n[AIT-934] feat(liveobjects): `LiveObjects` implementation to new path-based API (Kotlin)",
          "is_bot": false,
          "headline": "Merge pull request #1223 from ably/feature/liveobjects-kotlin-impleme…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T11:49:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "39e8d091d8bf26ba35fbca5c84fa4ca7cc41f545",
          "body": "[AIT-1008] Translate LiveObjects `objects` UTS test specs to Kotlin tests",
          "is_bot": false,
          "headline": "Merge pull request #1222 from ably/feature/uts-liveobjects-unit-tests",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T11:38:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd26bd89cff17a8f221196a271e3b3ea6e75ac3b",
          "body": "…opagation\n\nRename the DefaultRealtimeObject async bridges for clarity: asyncApi -> asyncFuture\n(generic, value-returning) and asyncVoidApi -> asyncVoidFuture (the Unit->Void adapter\nrequired by the Java write APIs), updating all call sites. Behaviour is unchanged; the\nthenApply { null } bridge stay\n[…]\npropagation for both\nhelpers, and - crucially - that a failed operation does not cancel the shared sequential\nscope for subsequent operations, locking in the SupervisorJob failure-isolation guarantee.",
          "is_bot": false,
          "headline": "refactor(liveobjects): rename async future helpers and cover their pr…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T11:33:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6b4f989e947efd840dfacec0b476b80fc2a15f12",
          "body": "…er overloads\n\nThe parameterless increment()/decrement() on both DefaultLiveCounterPathObject and\nDefaultLiveCounterInstance duplicated the full body of their Number counterparts with\na hardcoded 1. Make them delegate to increment(1)/decrement(1) instead. All spec\nchecks live in the parameterized overload, and the default-of-1 spec points\n(RTPO17a1/RTPO18a1, RTINS14a1/RTINS15a1) are preserved on the delegating methods.\nPure refactor, no behaviour change.",
          "is_bot": false,
          "headline": "refactor(liveobjects): delegate no-arg counter mutators to their Numb…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T11:05:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4a939ca34656def05fa420aba02541687aed7448",
          "body": "…lution\n\nresolveValueAtPath always received the PathObject's own path property at every\ncall site, so the parameter was redundant. Make it a no-arg method that resolves\nthe instance's stored path directly, and rename it to resolveValueAtCurrentPath\nto reflect that it only ever resolves this node's c\n[…]\nrty, so a future resolveValueAtPath(path) call inside it would have\nresolved the argument instead of the node's path. The no-arg form makes that\nmistake impossible. Pure refactor, no behaviour change.",
          "is_bot": false,
          "headline": "refactor(liveobjects): drop redundant path param from PathObject reso…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T10:52:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "98628781453261009845aa3f0065f5f605c944fb",
          "body": "…s type's file\n\nThe toCompactJsonElement() extension only reads WireObjectData's own fields and is\nused across packages (path, livemap), so it belongs with the type it extends rather\nthan in the livemap feature file. Move it into message/WireObjectMessage.kt alongside\nthe other WireObjectData extens\n[…]\nize, isInvalid); retarget the DefaultPathObject\nimport and drop the now-unused gson imports from InternalLiveMap. Pure move, no\nbehaviour change; message still has no dependency on value/path/livemap.",
          "is_bot": false,
          "headline": "refactor(liveobjects): move WireObjectData.toCompactJsonElement to it…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T10:43:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c8197d77b48644f0716a241d4f0faee6a1380d22",
          "body": "…LiveObject\n\nMove the ObjectUpdate sealed hierarchy (NoOp/MapUpdate/CounterUpdate) and its\nnoOp extension into a dedicated value/ObjectUpdate.kt, leaving BaseRealtimeLiveObject\nfocused on the base class. ObjectType stays with the base class as the broad object\ndiscriminator used across the package.\n\n[…]\nandling\n(e.g. tombstone) still compiles. Pure code move, no behaviour change.\n\nAlso drop a stale @Suppress(RedundantNullableReturnType) on\nDefaultLiveMapInstance.get, whose nullable return is genuine.",
          "is_bot": false,
          "headline": "refactor(liveobjects): extract ObjectUpdate model out of BaseRealtime…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-09T10:25:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "24921566b7ac9d0d8a416da0f16f3633e8695cc4",
          "body": "…align ensureAttached to RTL33\n\nRebuild PathObjectSubscriptionRegister on ably-java's EventEmitter — the SDK's\nthread-safe registration/dispatch primitive already used by the LiveMap/LiveCounter\nchange coordinators — replacing the hand-rolled ConcurrentHashMap + AtomicLong id\ncounter. PathEvent carr\n[…]\n ErrorInfo is propagated unchanged (RTL33b/b1)\n- FAILED (and any other state) throws code 90001 / statusCode 400 via objectException (RTL33c)\n\nRefresh HelpersTest to cover the full RTL33 state matrix.",
          "is_bot": false,
          "headline": "refactor(liveobjects): back path subscriptions with EventEmitter and …",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-08T18:18:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b0304acaa2e1eb192bf413fd1cc760892253ac76",
          "body": "[AIT-1038] chore(examples): migrate LiveObjects example app to the path-based API",
          "is_bot": false,
          "headline": "Merge pull request #1225 from ably/chore/update-liveobjects-example-app",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-07-08T12:46:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c6b5b51147d1f237fb15d97bcef944ee72f3970",
          "body": "…rrected spec\n\nProxy session creation failed with HTTP 400 for any rule using a frame-action\nmatch: the uts-proxy's MatchConfig.match.action is a Go string (action name or\nnumeric string), but the rule builders serialised messageAction as a JSON\nnumber. wsFrameToClientRule/wsFrameToServerRule now se\n[…]\n1; uts/README.md's GitHub URLs are left until that PR\nreaches main. See PROXY_UTS_SPEC_FIX.md for the full evidence chain.\n\nAll five ObjectsFaultsTest tests pass against the sandbox through uts-proxy.",
          "is_bot": false,
          "headline": "fix(uts): repair proxy test infra and align ObjectsFaultsTest with co…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-04T17:37:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4a173c85de3fa19c20e8a25283da14a90e977777",
          "body": "Review fixes for #1225:\n\n- getOrCreateCounter/getOrCreateMap now check the resolved type\n  (getType() != LIVE_COUNTER/LIVE_MAP) instead of exists(), so a\n  wrong-typed value at the key is replaced rather than returned as a\n  view whose reads yield null and writes fail; the LWW resolution of\n  the in\n[…]\n channel.object.on(SYNCING/SYNCED) state API, with the initial state\n  derived from root readiness since state events fire on transitions\n  only\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(examples): address review - type-safe get-or-create, sync status UI",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-03T11:35:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ba9934ef4ff222440480c0af333560884c9b62d6",
          "body": "The example app targeted the removed io.ably.lib.objects callback API\n(getRootAsync, createCounterAsync, LiveMapValue.asLiveCounter). Rewrite\nits bridge layer (Utils.kt) against the public path-based interfaces in\nio.ably.lib.liveobjects, entered via channel.object.get() which returns\nthe root LiveM\n[…]\ninstrumentation tests are\nunchanged. Verified with :examples:assembleDebug,\n:examples:compileDebugAndroidTestKotlin and manually on an emulator.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(examples): migrate LiveObjects example app to the path-based API",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-03T10:58:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b50f9048e89e7b7622acc3d55cf4abc7985dc904",
          "body": "…ubscriptions and event bubbling\n\nCompletes the path-addressed LiveObjects API on top of the sync engine:\n\n- Bridge ResolvedValue (MapRef/CounterRef/Leaf) to the internal graph\n  objects so path resolution returns live references\n- Replace the untyped ObjectUpdate with a sealed model\n  (MapUpdate/Co\n[…]\nMake stored path strings round-trip-safe by escaping backslashes as\n  well as dots in PathSegments#join\n- Remove dead createMap/createCounter code paths and re-enable the UTS\n  liveobjects test suites",
          "is_bot": false,
          "headline": "feat(liveobjects): implement path-based public API - reads, writes, s…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-03T09:52:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b8c16e1fda1aed8c87aa03a0d7dd58cd39c5aa5d",
          "body": "…PI preconditions to callers\n\nSpec-point migration (path-based API):\n- Replace deprecated/renamed spec-point references throughout the liveobjects\n  impl and the ObjectsMapEntry interface with their current equivalents:\n  access/write preconditions -> RTO25/RTO26, map/counter create steps ->\n  RTLMV\n[…]\nurns the no-op update (ObjectUpdate(null)) for\n  an empty map diff / zero counter delta, so notifyUpdated() short-circuits and\n  no spurious change event is emitted when clearing an empty root object.",
          "is_bot": false,
          "headline": "refactor(liveobjects): align spec points to path-based API and move A…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-02T12:13:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8006b9eb35c451b18427b0a475e57621f7b46902",
          "body": "…alue types\n\nFills in the Kotlin implementation behind the LiveObjects public interfaces\n(lib/.../liveobjects), replacing the TODO stubs in DefaultRealtimeObject with\na working objects sync engine and the LiveCounter / LiveMap value types.\n\nSync engine (io.ably.lib.liveobjects):\n- ObjectsManager    \n[…]\ns and reflective constructor signatures, plus\n  added keeps for WireObjectDataJsonSerializer and the Wire* message model that\n  Gson (de)serializes by field-name reflection on the JSON transport path.",
          "is_bot": false,
          "headline": "feat(liveobjects): implement path-based LiveObjects sync engine and v…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-07-02T12:11:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f255792c849b28403b166c144aaeeec636df8fdf",
          "body": "Align the skill's Step 6 with the spec manual (ably/specification#498) so a\ndiagnosed UTS spec error is handled spec-first instead of being quietly\nadapted to green:\n\n- Step 6 intro now names three acceptable end-states (spec-correct pass,\n  SDK deviation stays green, UTS spec error fails fast) — re\n[…]\nrns for a diagnosed\n  failure\" since fail-fast is not a deviation.\n- Defer the deviations-file entry format to the manual's \"Recording\n  deviations\" sections (removes the divergent inline field list).",
          "is_bot": false,
          "headline": "docs(uts-to-kotlin): spec-first fail-fast for UTS spec errors in Step 6",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T15:18:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dcf733ecf34692c6c0deda1c72ae345495ad7892",
          "body": "…nted\n\nThe liveobjects SDK has no implementation yet, so the translate-only liveobjects\ntests fail at runtime with \"LiveObjects plugin hasn't been installed\". Exclude\nthem from runUtsUnitTests and runUtsIntegrationTests (unit + integration standard\nand proxy) so the CI gates pass; they still compile via compileTestKotlin.\n\nMarked with a TODO to remove the exclusions once the liveobjects implementation\nis in place.",
          "is_bot": false,
          "headline": "test(uts): exclude liveobjects tests from uts run tasks until impleme…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T11:08:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb442b13bf9c375fbfcdc03dd431df6e04f98ee9",
          "body": "Running the Step 7 faithfulness audit (audit_translation.py) across the objects\nmodule surfaced three undocumented intentional omissions in the unit tests. Each\nis benign but was not recorded as a deviation; add entries so the audit\nreconciles clean:\n\n- RTPO10/10d/11/11d — `keys()`/`values()` \"IS Ar\n[…]\ned to RTO26 with no executable spec content, so the marker\n  entry is intentionally not translated (LiveCounterApiTest).\n\nIntegration and proxy objects tests audited clean; no deviations needed there.",
          "is_bot": false,
          "headline": "docs(uts): document objects translation deviations found by audit",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T11:03:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ea4bc9198fb8c92f7c488a3f28472202670bec36",
          "body": "…ture/uts-liveobjects-unit-tests",
          "is_bot": false,
          "headline": "Merge branch 'feature/path-based-liveobjects-implementation' into fea…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T10:43:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e2ad9b584aba4786f1cebe27dfa0b60341afb77a",
          "body": "read_text()/write_text() default to the locale encoding on Windows (often\ncp1252, not UTF-8) and apply newline translation, which would both mis-handle\nnon-ASCII content and rewrite the git-tracked uts-package-mapping.json with\nCRLF. Pin the read to utf-8 and write via write_bytes (binary mode does zero\nnewline translation on any OS or Python version, keeping the file LF — unlike\nwrite_text(newline=...), which needs Python 3.10+). Aligns with the utf-8 reads\nalready in audit_translation.py.",
          "is_bot": false,
          "headline": "fix(uts-skill): make resolve_uts.py file I/O Windows-safe",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T10:42:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0834c4557fd985769644b948f0bb154b488e7374",
          "body": "[AIT-1081] Update liveobjects `uts-to-kotlin` skill to generate tests",
          "is_bot": false,
          "headline": "Merge pull request #1221 from ably/feature/liveobjects-uts-tests",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T10:29:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d11eb61b6504e79405dfd516db45db2ae04abf3f",
          "body": "Translation review (SKILL.md Step 7) relied on eyeballing the spec and the\ngenerated Kotlin side-by-side to confirm every test case, setup step, operation\nand assertion was carried over — exactly the mechanical comparison the model\ndoes inconsistently. Add a bundled extractor so the review reconcile\n[…]\nit first and reconciles its output line by line\n(coverage + completeness), keeping setup-fidelity and deviation-honesty as the\nsemantic checks; paths reference the resolver's specs[].file / targetDir.",
          "is_bot": false,
          "headline": "feat(uts-skill): add deterministic spec-faithfulness audit to Step 7",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T10:27:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6f2c56ddee7aaf6d796de4df017b62f4fa78d9c7",
          "body": "- objects-mapping.md: correct helper filename casing helpers.kt -> Helpers.kt\n  (broken source-nav on case-sensitive filesystems); tag bare code fences as\n  `text` to clear markdownlint MD040.\n- README.md: tag bare fences as `text`; correct the msgpack rationale — ably-java\n  does implement msgpack \n[…]\ncapture\n  list (written on the SDK transport thread, read on the coroutine dispatcher)\n  to remove a visibility race / flake risk.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs/test: apply CodeRabbit + Copilot PR review fixes",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-30T09:58:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9f0e8abc68993dd79e69e0b96f76caf575d44b97",
          "body": "Applied on top of the merge of feature/liveobjects-uts-tests:\n- Point the liveobjects integration/proxy tests (ObjectsFaultsTest,\n  ObjectsLifecycleTest, ObjectsSyncTest) at SandboxApp.sandboxHost,\n  matching the consolidated sandbox-host constant.\n- Update objects-mapping.md (§12 nested-cause, §14 \n[…]\n.kt (case + content).\n\nCompiles clean (:uts:compileTestKotlin). The liveobjects tests remain\ntranslate-only at runtime (pending LiveObjects plugin wiring in the test\nharness); the realtime tiers pass.",
          "is_bot": false,
          "headline": "feat(uts): align liveobjects tests with sandbox host refactor",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-29T18:54:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "be6b8c10ef25b25fd738226d5365c7548d247748",
          "body": "…ects-unit-tests",
          "is_bot": false,
          "headline": "Merge branch 'feature/liveobjects-uts-tests' into feature/uts-liveobj…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-29T18:33:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0c59d15c7a72577ccac2c7a59dda3d7d1abee801",
          "body": "…efactor\n\n- Add ChannelHistoryTest (RTL10d) and TokenRequestTest (RSA9/RSA9a/RSA9g)\n  direct-sandbox integration tests, parameterised over json/msgpack.\n- Add junit-jupiter-params dependency (@ParameterizedTest / @ValueSource).\n- Consolidate the sandbox host into a single SandboxApp.sandboxHost cons\n[…]\ntlin SKILL.md for the\n  direct-sandbox tier: new ChannelHistoryTest walkthrough, integration-tests\n  umbrella section, section renumber.\n- Rename unit liveobjects helpers.kt -> Helpers.kt (case-only).",
          "is_bot": false,
          "headline": "feat(uts): realtime direct-sandbox integration tests + sandbox host r…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-29T18:11:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9a48df15852a94a4599307c63bca014c1f69f5a5",
          "body": "…ation/proxy tests",
          "is_bot": false,
          "headline": "Updated liveobjects integration helper and completed remaining integr…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-26T12:12:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60dccf4065a5f5bd5e0b7ba75e690391dd581096",
          "body": "Add the integration-tier translation of standard_test_pool.md's REST fixture\nprovisioning (`provision_objects_via_rest`) under\nuts/.../integration/standard/liveobjects/helpers.kt: `provisionObjectsViaRest`\nplus op builders (mapSet/mapRemove/mapCreate/counterCreate/counterInc) and value\nbuilders (str\n[…]\nocument it in the uts-to-kotlin skill's objects-mapping.md as a new section\n(\"14. Integration-test helpers\"), promoted out of the unit-only internal-graph\nsection, with the TOC renumbered accordingly.",
          "is_bot": false,
          "headline": "feat(uts): add LiveObjects integration REST fixture-provisioning helper",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-26T10:51:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "43a3ab24ebf672fb56b7daad4514e098c1a8dc07",
          "body": "…s.md\n\nRecord the five objects/unit UTS specs (live_counter, live_map, object_id,\nobjects_pool, parent_references) that cannot be translated into the :uts\nmodule. They assert on the internal CRDT graph (ObjectsPool, live nodes,\napplyOperation, object-id generation, parent references), which is (a) n\n[…]\nhy\nthese target internals, the two blockers, and the realistic visibility options\n(java-test-fixtures bridge, tests in :liveobjects/src/test, or reflection) with\ntheir trade-offs and a recommendation.",
          "is_bot": false,
          "headline": "docs(uts): document untranslatable objects specs in private_deviation…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-26T09:54:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e38b889958363a6140bdd395e8b27ed28ab49df1",
          "body": null,
          "is_bot": false,
          "headline": "Generated unit tests using `uts-to-kotlin` skill",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T20:56:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "752b45ee5e9f7b8e796d032d5a0f81a1880c8096",
          "body": "…ap them\n\nTranslate objects/helpers/standard_test_pool.md into ably-java test helpers in\nuts/.../unit/liveobjects/helpers.kt: the standard object pool, the protocol- and\nobject-message builders (emitting the integer-coded wire JSON the SDK's Gson\nexpects), setupSyncedChannel/NoAck over the existing \n[…]\nit-test helpers\"\nsection mapping each spec helper to its Kotlin name, and §11/§13 are corrected to\nnote public_object_message.md is translatable via buildPublicObjectMessage rather\nthan internal-only.",
          "is_bot": false,
          "headline": "feat(uts): add LiveObjects unit-test helpers (standard_test_pool) + m…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T19:45:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0068fe918500830d6cc98c31da236c44f695fc8e",
          "body": "…rence\n\nThe objects UTS specs are written in ably-js-style pseudocode, but ably-java\nis a typed SDK (RTTS1-10 partition). Add references/objects-mapping.md mapping\neach ably-js symbol to its ably-java equivalent: entry point, async\n(CompletableFuture/await), the typed PathObject/Instance hierarchies\n[…]\neference\nvia a `notes` field in uts-package-mapping.json; resolve_uts.py resolves it to\n`translationNotes` (absolute path, or null), and SKILL.md makes it required\nreading before Phase 2 when present.",
          "is_bot": false,
          "headline": "feat(uts-to-kotlin): add ably-js → ably-java liveobjects mapping refe…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T18:50:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0aaec3981b84291c21d773b60897058db18ceb1d",
          "body": "…aluate mode\n\nMake the skill's selection phase deterministic and add an explicit\ntranslate-vs-evaluate choice:\n\n- Add scripts/resolve_uts.py — a bundled resolver that validates the module\n  directory, reads uts-package-mapping.json, and emits JSON with, per tier,\n  the target dir, Kotlin package, an\n[…]\nowed-tools).\n- Fix the file template to use the resolver's package/className (no hardcoded\n  realtime, no double Test suffix) and the spec's full @UTS id; correct stale\n  uts/test/... proxy doc paths.",
          "is_bot": false,
          "headline": "feat(uts-to-kotlin): deterministic selection via resolver script + ev…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T16:57:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "940b65f0f18d5b8826ef7bdd9fd522c211f78329",
          "body": "…ckage mapping\n\nRework the uts-to-kotlin skill to translate a whole UTS module at once\ninstead of a single spec file:\n\n- Take a UTS module directory (e.g. .../specification/uts/objects) and\n  validate it sits directly under uts/ with a standard tier structure.\n- Resolve the target ably-java package \n[…]\nlation steps.\n\nPhase 1 (selection: Steps A-D) is new; Phase 2 (per-spec translation:\nSteps 1-7) keeps the existing rules, with Step 1/2 adjusted to consume the\nlooped spec and the pre-resolved target.",
          "is_bot": false,
          "headline": "feat(uts-to-kotlin): drive the skill from a module directory via a pa…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T12:27:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a53996c4e0bb9f531ef896c13805ebaa798123ee",
          "body": "Reflect the new test-source structure in the UTS guide, website, and the\nuts-to-kotlin skill:\n\n- Add the direct-sandbox (`integration/standard/<module>/`) tier alongside\n  the existing unit and proxy tiers, and document that every tier is now\n  organised by module (`realtime`, `liveobjects`, …).\n- U\n[…]\nule>`, add a\n  direct-sandbox row, and split integration specs into fault-injecting (proxy)\n  vs happy-path (direct sandbox) flows.\n- Correct stale \"both tiers\" wording now that there are three tiers.",
          "is_bot": false,
          "headline": "docs(uts): document direct-sandbox tier and per-module test layout",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T11:43:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "aa0504e60dec6b5ea795906d22c06b6c7e1a6360",
          "body": "…ier Gradle tasks\n\nReorganise the uts module under a domain-rooted io.ably.lib.uts package that\ncleanly separates infrastructure from tests, and unit from integration:\n\n  infra/                         shared awaits (Utils.kt)\n  infra/unit/                    mock transports + ConnectionDetails buil\n[…]\ns.\n- check.yml now runs :uts:runUtsUnitTests; integration-test.yml gains a check-uts\n  job running :uts:runUtsIntegrationTests.\n- Bring uts/README.md and uts/index.html in sync with the new structure.",
          "is_bot": false,
          "headline": "refactor(uts): split test sources into unit/integration tiers + per-t…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T11:25:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f98d4641df82be50d41de70b86ca06a2a6bf5815",
          "body": "Move the human-readable UTS guide and its self-contained HTML rendering\ninto the uts/ module as README.md and index.html. Both cover the UTS\nconcept, the three test tiers, the spec docs, the uts/ module layout,\nmock/proxy infrastructure, the two example tests, deviations, and\nappendices. Spec-doc references link to GitHub; paths are fully\nqualified; the two artifacts are kept in sync.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(uts): add UTS guide (README.md) and standalone website (index.html)",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T09:53:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6ec5d809732779707b8c78dc9b2d12a142e9fd24",
          "body": null,
          "is_bot": false,
          "headline": "Generated UTS doc to better understand the existing UTS infra.",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-25T09:09:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b56407f492869eb0b8d6777ec5938d8488045cf7",
          "body": "…veobjects-implementation",
          "is_bot": false,
          "headline": "Merge remote-tracking branch 'origin/main' into feature/path-based-li…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T17:18:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6793dfaf79d4147225b9e9094f8e7278cd0f070",
          "body": "…-to-liveobjects\n\n[AIT-1037] Refactored `object` package name to `liveobjects`",
          "is_bot": false,
          "headline": "Merge pull request #1220 from ably/chore/refactor-object-package-name…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T17:18:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f45a93faf569484504b8e76187efa341238139df",
          "body": null,
          "is_bot": false,
          "headline": "Fixed android emulate workflow by fixing correct import",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T12:31:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "abcd0228cff5fb65ccab5e9bef890ed122a040ee",
          "body": "uts: add `ProxyManager` and `ProxySession` for integration tests",
          "is_bot": false,
          "headline": "Merge pull request #1210 from ably/AIT-767/proxy-support",
          "author_name": "Evgeny Khokhlov",
          "author_login": "ttypic",
          "committed_at": "2026-06-24T12:15:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23efe8270a1c0c7f26db91458a73caba816b9fcd",
          "body": null,
          "is_bot": false,
          "headline": "Refactored object package name to domain specific liveobjects",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T12:10:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f52cca6539437d3f453f5c7dc74045b181d000e",
          "body": "…g `RecoveryKeyContext#channelSerials`\n\nas a treemap",
          "is_bot": false,
          "headline": "Fixed flaky `should_encode_recovery_key_context_object` test by makin…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T11:46:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83e347ced20ba904b28965883f2033cfe13384d7",
          "body": "- Added basic helper unit/integration tests to `io.ably.lib.object`",
          "is_bot": false,
          "headline": "- Removed `io.ably.lib.objects` package and relevant tests",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T11:44:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e26ed390d0a8872d64d87ba5e8d3103ea85efc6f",
          "body": "…lization\n\n[AIT-1009] Implement Json and MsgPack serializers for path-based LiveObjects",
          "is_bot": false,
          "headline": "Merge pull request #1218 from ably/chore/path-based-liveobjects-seria…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T09:50:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7ab9482117f5a6d92b94f5b68bb4c37222caed09",
          "body": null,
          "is_bot": false,
          "headline": "Fixed `LiveObjectsPlugin#getInstance` method to return RealtimeObject",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-24T09:49:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18f4a68feca703bfee0c551c60210631f188aaa8",
          "body": "…ction state tests\n\n- Added support for using locally built `uts-proxy` binaries or distributives via system property or environment variable.\n- Improved `AuthReauthTest` by simplifying connection state listener and reauth verification logic.\n- Updated Gradle test task to propagate local proxy paths.",
          "is_bot": false,
          "headline": "uts: support local proxy binaries in `ProxyManager` and improve conne…",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-06-24T09:35:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba266f263da367c90badccb0110b869c45a747d8",
          "body": "- ProxyManager: fix binary cache check (a present+executable binary is a hit;\n  the prior check compared the extracted binary's hash to the *archive* checksum\n  and never matched, re-downloading every run); add JVM shutdown hook + real\n  stopProxy() so the child process is reaped; read-and-discard T\n[…]\nenSigner in a nested\n  finally; add RTC8a @UTS tag.\n- SKILL.md: app.apiKey -> app.defaultKey, deafultKey typo, getLog List<Event>.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "uts: address proxy integration test review feedback",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-23T13:36:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eded262a0dc8d5151c2db92c27321a0c5f16e644",
          "body": "… lifecycle management\n\n- Introduced `ProxyManager` to manage the `uts-proxy` binary lifecycle, including downloading, verification, and process control.\n- Added `ProxySession` for managing proxy sessions with rules, actions, event logging, and cleanup.\n- Included KDoc documentation for clear usage guidelines in integration tests.",
          "is_bot": false,
          "headline": "uts: add `ProxyManager` and `ProxySession` for integration test proxy…",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-06-23T11:34:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3471b02bf851bddbc8ef73df577ea6aebeb57d1a",
          "body": "…entation\n\n[AIT-928] Added basic impl. for PathObject and Instance interfaces",
          "is_bot": false,
          "headline": "Merge pull request #1217 from ably/chore/liveobjects-add-basic-implem…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-06-22T08:22:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e8f70c99680bac8b0b6bf958951799afd59c249",
          "body": "- Added TODO for `resolveValueAtPath` based on review comment",
          "is_bot": false,
          "headline": "- Updated Adapter#getChannel with readonly way to retrieve channel",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-22T08:16:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c489ac05769541257bc24ed31f9b50971bd0cd48",
          "body": null,
          "is_bot": false,
          "headline": "Updated validation checks/log messages as per review comments",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-22T07:44:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfa574f7a52d6893c5e0e6211132633386370617",
          "body": null,
          "is_bot": false,
          "headline": "Implemented `LiveObjectsPlugin` interface with relevant Factory method",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-19T12:27:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "863f1f632c516950989d6558c27964d2229a9374",
          "body": "Fixes checkstyle AvoidStarImport violation on com.google.gson.*.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Replace gson star import with explicit imports in ObjectJsonSerializer",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-19T12:24:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ad10253bc5a5c177aedad03ca2914277b7e76084",
          "body": "Point the JSON and MsgPack serializers in io.ably.lib.object.serialization\nat the new WireObjectMessage wire model instead of the legacy\nio.ably.lib.objects.ObjectMessage, so the new `object` package has no\ndependency on the legacy `objects` package.\n\n- DefaultSerialization: implement the new Object\n[…]\ne-format\n  fidelity - @SerializedName(\"object\") on objectState and\n  @JsonAdapter(WireObjectDataJsonSerializer) on WireObjectData.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Retarget path-based serializers to WireObjectMessage model",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-19T12:21:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5e452c29f664699338de01fc68475474d570fcec",
          "body": "- Implemented JsonSerializer annotation for better json handling",
          "is_bot": false,
          "headline": "- Declared ObjectSerializer interface for json/msgpack encoding/decoding",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-19T12:12:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34c3bbeeffbc01d2a2090af89ea34a5de8eda54c",
          "body": null,
          "is_bot": false,
          "headline": "Implemented Json and MsgPack serializers for path based liveobjects",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-18T18:03:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8a283d7b2b8b25c22596ff1dace5a55c630ff59",
          "body": null,
          "is_bot": false,
          "headline": "Updated PathObject#value checks for primitives as per spec",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-18T17:48:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "94b96a406c069e80064c6708fec4cea889d206b5",
          "body": null,
          "is_bot": false,
          "headline": "Refactored javadoc for Instance interface, fixed other spec doc comments",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-18T11:04:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3c25c13dc4259248e89c7205f97d6cb8426bf1fe",
          "body": null,
          "is_bot": false,
          "headline": "Added liveobjects read/write operation validation",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T15:34:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0a9ea026ff19d49e8dc6aa531a6257fe2af680dd",
          "body": "… to ably-js",
          "is_bot": false,
          "headline": "Implemented resolveValueAtPath guards for terminal operations similar…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T12:31:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54ae53f0f1eaad4d3fdb94e75919c1b843f6d76b",
          "body": "- Marked PathObject#getValue as nullable when value doesn't exist at given path",
          "is_bot": false,
          "headline": "- Implemented ResolvedValue class for resolving value at given path",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T12:04:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f74ae1d8ece47e34b38f197c70965692bbae4f3f",
          "body": "…onArray",
          "is_bot": false,
          "headline": "Updated instance types to return specific JsonPrimitive/JsonObject/Js…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T11:20:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af0b39eacac7fdbca953af0c209b83634235b528",
          "body": null,
          "is_bot": false,
          "headline": "Added default skeleton implementation for LiveCounter and LiveMap",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T10:59:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "548c0b569462e99b431452e4376453dfe663b853",
          "body": "… relevant\n\nerror codes under `Errors.kt`",
          "is_bot": false,
          "headline": "Added impl. for DefaultObjectMessage and WireObjectMessage along with…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T10:28:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68edd4b253133a417f5cd0486281a915598cfba4",
          "body": "…mplementation' into chore/liveobjects-add-basic-implementation",
          "is_bot": false,
          "headline": "Merge remote-tracking branch 'origin/feature/path-based-liveobjects-i…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-17T09:22:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6227b756922e4b11dcf6486c9f371746d94726fb",
          "body": null,
          "is_bot": false,
          "headline": "Added basic impl. for PathObject and Instance liveobjects interfaces",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-16T17:41:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18485d6b675fc69f2d9b744a8e4cee49f726b52f",
          "body": "…tion-for-path-based-interfaces\n\n[AIT-928] feat(liveobjects): add path-based RealtimeObject and channel.object accessor",
          "is_bot": false,
          "headline": "Merge pull request #1216 from ably/chore/liveobjects-basic-implementa…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-06-16T12:00:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f053c49dde7bb195a740f0460a9b9847eb6c2d4a",
          "body": "…ture\n\n- Replaced ObjectsSubscription import with Subscription as per requirement",
          "is_bot": false,
          "headline": "- Marked `channel.object.get` method non-blocking using completablefu…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-16T11:28:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfb6de12dfffc8fb047200193bb2625f498fe2ee",
          "body": "…ccessor\n\nIntroduce the public, strongly-typed, path-based LiveObjects entry point on a\nrealtime channel, accessed via `channel.object`.\n\n- RealtimeObject: exposes `get()` returning the root LiveMapPathObject, and\n  extends ObjectStateChange to subscribe to objects sync-state events\n  (on/off/offAll\n[…]\nses the new io.ably.lib.object.RealtimeObject type (getInstance\ncurrently returns the legacy io.ably.lib.objects.RealtimeObjects).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(liveobjects): add path-based RealtimeObject and channel.object a…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-15T14:04:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4f35df8318d184aa40fc29681b3514bdd32e7536",
          "body": "…al-public-api\n\n[LiveObjects] Implement path-based LiveObjects public API",
          "is_bot": false,
          "headline": "Merge pull request #1213 from ably/feature/path-based-liveobjects-fin…",
          "author_name": "sachin shinde",
          "author_login": "sacOO7",
          "committed_at": "2026-06-11T12:38:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "11e87a7e4b21a17d4a824fa3f1b62acda2d721ac",
          "body": "- PathObjectSubscriptionOptions: validate depth fail-fast per RTPO19c1a,\n  throwing AblyException with ErrorInfo(400, 40003) when depth <= 0.\n  Depth is now a primitive int; the \"no depth / infinite depth\" state is\n  expressed via a new no-arg constructor (mirrors ably-js `{}` options),\n  so no null\n[…]\n/JsonArrayPathObject: reword \"primitive resolution\"\n  javadoc for clarity\n- LiveMapPathObject#at: fix javadoc equivalence example to compile\n  (get() returns base PathObject, so chain via asLiveMap())",
          "is_bot": false,
          "headline": "Addressed PR review comments on liveobjects public API",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-11T10:54:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "59a5ecccf10d500788e70d4c5c196b915b1ae159",
          "body": null,
          "is_bot": false,
          "headline": "Moved subscribe methods to the bottom in `PathObject` interface",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-10T12:14:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "99d9dd9716accc956c0587fb3d6ceecfd92ce010",
          "body": null,
          "is_bot": false,
          "headline": "Refactored/Updated public API types as per spec",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-10T12:01:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e226ba45219544985ec263b8615dff622c11f8ed",
          "body": "…assessment doc",
          "is_bot": false,
          "headline": "Updated PathObject and Instance classes/sub-classes as per finalized …",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-09T10:44:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "041043257b548e15a55996909c304f5bfa98f243",
          "body": "…ance class",
          "is_bot": false,
          "headline": "Implemented path-based liveobjects public API for PathObject and Inst…",
          "author_name": "sacOO7",
          "author_login": "sacOO7",
          "committed_at": "2026-06-08T12:50:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0e5e6842bc0a2ba2e23c5b930c7491964b01b822",
          "body": "[AIT-767] uts: live objects ground work",
          "is_bot": false,
          "headline": "Merge pull request #1209 from ably/AIT-767/live-object-ground-work",
          "author_name": "Evgeny Khokhlov",
          "author_login": "ttypic",
          "committed_at": "2026-06-01T09:15:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93226748adac28a70519528f4c8e06786f2f59e1",
          "body": "- moved uts infrastructure related files into `uts.infra`\n- updated skill\n- simplify code in constructor",
          "is_bot": false,
          "headline": "uts: add nanoTime support to `Clock` and update usages for consistency",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T12:47:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a689d45850b9c05bf39519a4e133a65327ea20d",
          "body": null,
          "is_bot": false,
          "headline": "uts: mock object.wait(timeout) calls as well",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:10:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83a6634b14ac5ced0993f229276f16a87d72e65c",
          "body": null,
          "is_bot": false,
          "headline": "uts: updated skill to reference spec guide for writing tests",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:10:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a92d5e3ba934699f354565579a0236ff8415a938",
          "body": "- Added KDoc comments to `FakeClock`, `MockHttpClient`, and `MockWebSocket` explaining their purpose and usage.",
          "is_bot": false,
          "headline": "uts: add inline documentation for fake clocks, HTTP, and WebSocket mocks",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:10:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1605062dc32c66f539b2308c35238ab77bc9acda",
          "body": "…onnections\n\n- Added `queryParams` field and `parseQueryString` utility for `PendingConnection` implementations.\n- Updated `MockWebSocketEngineFactory` and `MockHttpEngine` to parse and pass query parameters.\n- Enhanced connection recovery tests with assertions on query parameters.",
          "is_bot": false,
          "headline": "uts: add support for query parameter parsing and assertions in mock c…",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:10:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e215a1cecf5cb55f191fc73fb27002066cfa76b",
          "body": "…ssage decoding\n\n- Added support for inspecting outgoing WebSocket frames (`MessageFromClient` events) in `MockWebSocket`.\n- Enhanced `ClientOptionsBuilder` to set `useBinaryProtocol = false` by default for JSON text frame testing.\n- Updated `ConnectionRecoveryTest` to assert on outgoing ATTACH messages.",
          "is_bot": false,
          "headline": "uts: add outgoing frame inspection and extend `MockWebSocket` with me…",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:10:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e22d41053e34d9e0314327932970825de712850b",
          "body": null,
          "is_bot": false,
          "headline": "uts: first UTS generation attempt",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:09:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07d9bd6e5598cc49f829c4380eae09624bc49e7a",
          "body": "…in tests\n\n- Introduced a new skill for converting UTS pseudocode specs into runnable Kotlin tests.\n- Included detailed translation rules for pseudocode to Kotlin, mock setup, and assertions.\n- Added file templates and steps for compilation, testing, and handling deviations.\n- Enhanced developer workflow for UTS test authoring.",
          "is_bot": false,
          "headline": "uts: add `uts-to-kotlin` skill for translating UTS pseudocode to Kotl…",
          "author_name": "evgeny",
          "author_login": "ttypic",
          "committed_at": "2026-05-29T11:09:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 100,
      "commits_last_year": 280,
      "latest_release_at": "2026-07-13T17:33:16Z",
      "latest_release_tag": "v1.8.0",
      "releases_from_tags": false,
      "days_since_last_push": 4,
      "active_weeks_last_year": 38,
      "days_since_latest_release": 12,
      "mean_days_between_releases": 32.1
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 45,
      "stars": 100,
      "watchers": 34,
      "fork_history": {
        "days": [
          {
            "date": "2015-08-23",
            "count": 1
          },
          {
            "date": "2015-09-08",
            "count": 1
          },
          {
            "date": "2015-11-12",
            "count": 1
          },
          {
            "date": "2015-12-10",
            "count": 1
          },
          {
            "date": "2015-12-16",
            "count": 1
          },
          {
            "date": "2015-12-25",
            "count": 1
          },
          {
            "date": "2016-01-02",
            "count": 1
          },
          {
            "date": "2016-04-08",
            "count": 1
          },
          {
            "date": "2016-08-05",
            "count": 1
          },
          {
            "date": "2016-08-17",
            "count": 1
          },
          {
            "date": "2017-03-11",
            "count": 1
          },
          {
            "date": "2017-07-25",
            "count": 1
          },
          {
            "date": "2017-07-31",
            "count": 1
          },
          {
            "date": "2017-10-09",
            "count": 1
          },
          {
            "date": "2017-10-24",
            "count": 1
          },
          {
            "date": "2018-01-10",
            "count": 1
          },
          {
            "date": "2018-06-04",
            "count": 1
          },
          {
            "date": "2018-08-13",
            "count": 1
          },
          {
            "date": "2018-10-29",
            "count": 1
          },
          {
            "date": "2019-01-02",
            "count": 1
          },
          {
            "date": "2019-05-08",
            "count": 1
          },
          {
            "date": "2019-10-23",
            "count": 1
          },
          {
            "date": "2020-09-30",
            "count": 1
          },
          {
            "date": "2021-01-11",
            "count": 1
          },
          {
            "date": "2021-02-10",
            "count": 1
          },
          {
            "date": "2021-03-24",
            "count": 1
          },
          {
            "date": "2021-10-25",
            "count": 1
          },
          {
            "date": "2022-03-15",
            "count": 1
          },
          {
            "date": "2022-04-01",
            "count": 1
          },
          {
            "date": "2022-05-28",
            "count": 1
          },
          {
            "date": "2022-12-02",
            "count": 1
          },
          {
            "date": "2023-06-21",
            "count": 1
          },
          {
            "date": "2023-09-11",
            "count": 1
          },
          {
            "date": "2023-12-15",
            "count": 1
          },
          {
            "date": "2024-03-22",
            "count": 1
          },
          {
            "date": "2024-07-14",
            "count": 1
          },
          {
            "date": "2024-11-26",
            "count": 1
          },
          {
            "date": "2025-05-14",
            "count": 1
          },
          {
            "date": "2025-08-15",
            "count": 1
          },
          {
            "date": "2025-09-30",
            "count": 1
          },
          {
            "date": "2025-11-09",
            "count": 1
          },
          {
            "date": "2026-01-15",
            "count": 1
          },
          {
            "date": "2026-02-25",
            "count": 1
          },
          {
            "date": "2026-03-29",
            "count": 1
          },
          {
            "date": "2026-07-06",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 45,
        "total_forks": 45
      },
      "star_history": null,
      "open_issues_and_prs": 139
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "example",
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "android/build.gradle.kts",
        "build.gradle.kts",
        "examples/build.gradle.kts",
        "gradle-lint/build.gradle",
        "java/build.gradle.kts",
        "liveobjects/build.gradle.kts",
        "network-client-core/build.gradle.kts",
        "network-client-default/build.gradle.kts",
        "network-client-okhttp/build.gradle.kts",
        "pubsub-adapter/build.gradle.kts",
        "uts/build.gradle.kts"
      ],
      "largest_source_bytes": 161962,
      "source_files_sampled": 456,
      "oversized_source_files": 8,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "android/build.gradle.kts",
        "build.gradle.kts",
        "examples/build.gradle.kts",
        "gradle-lint/build.gradle",
        "java/build.gradle.kts",
        "liveobjects/build.gradle.kts",
        "network-client-core/build.gradle.kts",
        "network-client-default/build.gradle.kts",
        "network-client-okhttp/build.gradle.kts",
        "pubsub-adapter/build.gradle.kts",
        "uts/build.gradle.kts"
      ],
      "advisories": {
        "error": "No resolved dependencies to assess",
        "scope": "repository_graph",
        "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": [
        "maven"
      ],
      "dependencies": [],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [],
        "collected": true,
        "truncated": false,
        "total_count": 0,
        "direct_count": 0,
        "indirect_count": 0
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 5,
        "merged_prs": 571,
        "open_issues": 134,
        "closed_ratio": 0.747,
        "closed_issues": 395,
        "closed_unmerged_prs": 122
      },
      "bus_factor": 3,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "paddybyers",
          "commits": 583,
          "avatar_url": "https://avatars.githubusercontent.com/u/1137574?v=4"
        },
        {
          "type": "User",
          "login": "sacOO7",
          "commits": 393,
          "avatar_url": "https://avatars.githubusercontent.com/u/16723785?v=4"
        },
        {
          "type": "User",
          "login": "ttypic",
          "commits": 272,
          "avatar_url": "https://avatars.githubusercontent.com/u/16488867?v=4"
        },
        {
          "type": "User",
          "login": "QuintinWillison",
          "commits": 241,
          "avatar_url": "https://avatars.githubusercontent.com/u/8318344?v=4"
        },
        {
          "type": "User",
          "login": "psolstice",
          "commits": 137,
          "avatar_url": "https://avatars.githubusercontent.com/u/14033990?v=4"
        },
        {
          "type": "User",
          "login": "funkyboy",
          "commits": 135,
          "avatar_url": "https://avatars.githubusercontent.com/u/348355?v=4"
        },
        {
          "type": "User",
          "login": "ikbalkaya",
          "commits": 106,
          "avatar_url": "https://avatars.githubusercontent.com/u/421091?v=4"
        },
        {
          "type": "User",
          "login": "AndyTWF",
          "commits": 80,
          "avatar_url": "https://avatars.githubusercontent.com/u/6977297?v=4"
        },
        {
          "type": "User",
          "login": "tcard",
          "commits": 77,
          "avatar_url": "https://avatars.githubusercontent.com/u/727422?v=4"
        },
        {
          "type": "User",
          "login": "gokhanbarisaker",
          "commits": 76,
          "avatar_url": "https://avatars.githubusercontent.com/u/914990?v=4"
        }
      ],
      "contributors_sampled": 38,
      "top_contributor_share": 0.242
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "check.yml",
        "emulate.yml",
        "example-app.yml",
        "features.yml",
        "integration-test.yml",
        "javadoc.yml",
        "release.yaml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": true,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 9,
            "reason": "binaries present in source code",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": null,
            "reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "7 out of 7 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 7,
            "reason": "Found 5/7 approved changesets -- score normalized to 7",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 27 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 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": 10,
            "reason": "all dependencies are pinned",
            "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": 6,
            "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": "74d267f1503e29022beb952a76deb0e5faeb9fa0",
        "ran_at": "2026-07-26T06:56:45Z",
        "aggregate_score": 6.6,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-13T17:42:08Z",
      "oldest_open_prs": [
        {
          "number": 1024,
          "created_at": "2024-07-31T09:13:56Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 1191,
          "created_at": "2026-02-12T15:32:37Z",
          "last_comment_at": "2026-02-12T15:32:51Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 1192,
          "created_at": "2026-02-19T23:31:12Z",
          "last_comment_at": "2026-02-19T23:31:31Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 1204,
          "created_at": "2026-03-25T16:30:44Z",
          "last_comment_at": "2026-03-25T16:30:50Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 1228,
          "created_at": "2026-07-21T12:26:19Z",
          "last_comment_at": "2026-07-21T12:30:40Z",
          "last_comment_author": "coderabbitai"
        }
      ],
      "last_merged_pr_at": "2026-07-13T17:29:36Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 9,
          "created_at": "2015-04-13T13:10:32Z",
          "last_comment_at": "2016-01-01T14:29:23Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 18,
          "created_at": "2015-04-22T13:07:18Z",
          "last_comment_at": "2015-04-22T13:08:58Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 29,
          "created_at": "2015-06-21T22:00:19Z",
          "last_comment_at": "2016-01-01T17:29:59Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 64,
          "created_at": "2016-01-02T19:09:05Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 76,
          "created_at": "2016-01-22T10:14:47Z",
          "last_comment_at": "2021-07-01T11:23:28Z",
          "last_comment_author": "paddybyers"
        },
        {
          "number": 105,
          "created_at": "2016-02-26T23:42:04Z",
          "last_comment_at": "2016-11-01T12:05:54Z",
          "last_comment_author": "paddybyers"
        },
        {
          "number": 109,
          "created_at": "2016-02-29T10:29:57Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 121,
          "created_at": "2016-03-14T12:13:47Z",
          "last_comment_at": "2016-03-16T09:23:27Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 169,
          "created_at": "2016-09-29T18:28:31Z",
          "last_comment_at": "2016-10-05T20:37:08Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 180,
          "created_at": "2016-10-13T15:51:20Z",
          "last_comment_at": "2016-10-13T16:57:37Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 202,
          "created_at": "2016-10-28T13:47:28Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 224,
          "created_at": "2016-11-10T15:59:54Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 232,
          "created_at": "2016-11-15T22:43:54Z",
          "last_comment_at": "2016-11-23T01:47:36Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 233,
          "created_at": "2016-11-16T01:02:29Z",
          "last_comment_at": "2016-11-23T01:46:54Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 259,
          "created_at": "2016-12-27T11:00:07Z",
          "last_comment_at": "2016-12-27T16:30:12Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 260,
          "created_at": "2016-12-27T11:03:00Z",
          "last_comment_at": "2016-12-27T13:13:45Z",
          "last_comment_author": "mattheworiordan"
        },
        {
          "number": 266,
          "created_at": "2017-01-04T16:51:51Z",
          "last_comment_at": "2019-11-13T10:55:50Z",
          "last_comment_author": "amihaiemil"
        },
        {
          "number": 357,
          "created_at": "2017-11-07T12:24:27Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 365,
          "created_at": "2018-02-23T12:18:22Z",
          "last_comment_at": "2018-03-23T14:11:23Z",
          "last_comment_author": "funkyboy"
        },
        {
          "number": 373,
          "created_at": "2018-03-16T09:04:59Z",
          "last_comment_at": "2018-03-16T09:25:58Z",
          "last_comment_author": "paddybyers"
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/ably/ably-java",
    "host": "github.com",
    "name": "ably-java",
    "owner": "ably"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 74,
      "inputs": {
        "security": 66,
        "vitality": 94,
        "community": 61,
        "governance": 75,
        "engineering": 70
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 94,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "commits_last_year": 280,
              "human_commit_share": 1,
              "days_since_last_push": 4,
              "active_weeks_last_year": 38
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "38/52 weeks with commits",
                "points": 26.3,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 38
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "280 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 280
                    }
                  }
                ],
                "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": 100,
              "latest_release_tag": "v1.8.0",
              "releases_from_tags": false,
              "days_since_latest_release": 12,
              "mean_days_between_releases": 32.1
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 12 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 12
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~32.1 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 32.1
                    }
                  }
                ],
                "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": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 12,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 12 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 12
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "moderate",
        "name": "Community & Adoption",
        "value": 61,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "forks": 45,
              "stars": 100,
              "watchers": 34,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "100 stars",
                "points": 32.4,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "45 forks",
                "points": 13.7,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 45
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "34 watchers",
                "points": 8.4,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 34
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "good",
        "name": "Sustainability & Governance",
        "value": 75,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "good",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 77,
            "inputs": {
              "bus_factor": 3,
              "contributors_sampled": 38,
              "top_contributor_share": 0.242
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "3 contributor(s) cover half of all commits",
                "points": 36,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 24% of commits",
                "points": 17.1,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 24
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "38 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 38
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 27 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 77,
            "inputs": {
              "merged_prs": 571,
              "open_issues": 134,
              "closed_issues": 395,
              "issue_closed_ratio": 0.747,
              "closed_unmerged_prs": 122
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "75% of issues closed",
                "points": 34.9,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 75
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "571/693 decided PRs merged",
                "points": 31.5,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 571,
                      "decided": 693
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 5/7 approved changesets -- score normalized to 7",
                "points": 10.5,
                "status": "partial",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "followers": 214,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "ably",
              "public_repos": 123,
              "account_age_days": 5151
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "214 followers of ably",
                "points": 16.8,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 214,
                      "login": "ably"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "123 public repos, account ~14 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 123
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 14
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 70,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "7 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "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": 6.4,
                "status": "met",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "7 out of 7 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [
                "java",
                "android",
                "realtime-messaging",
                "client-library",
                "rest",
                "realtime",
                "clojure",
                "scala",
                "sdk"
              ],
              "has_wiki": false,
              "homepage": "https://ably.com/download",
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://ably.com/download",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "9 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 66,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 66,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 6.6
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "binaries present in source code",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "7 out of 7 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 5/7 approved changesets -- score normalized to 7",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 27 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 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": "all dependencies are pinned",
                "points": 5,
                "status": "met",
                "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": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 14
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 58,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 35,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.65,
              "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": "65 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 34.7,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 65,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 66,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.08,
              "toolchain_manifests": [
                "android/build.gradle.kts",
                "build.gradle.kts",
                "examples/build.gradle.kts",
                "gradle-lint/build.gradle",
                "java/build.gradle.kts",
                "liveobjects/build.gradle.kts",
                "network-client-core/build.gradle.kts",
                "network-client-default/build.gradle.kts",
                "network-client-okhttp/build.gradle.kts",
                "pubsub-adapter/build.gradle.kts",
                "uts/build.gradle.kts"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "android/build.gradle.kts, build.gradle.kts, examples/build.gradle.kts (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "android/build.gradle.kts, build.gradle.kts, examples/build.gradle.kts"
                    }
                  }
                ],
                "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": "Java (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Java"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "8 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 8,
                      "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": "all dependencies are pinned",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "Java",
              "largest_source_bytes": 161962,
              "source_files_sampled": 456,
              "oversized_source_files": 8
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Java (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Java"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "8/456 source files over 60KB",
                "points": 54,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 456,
                      "oversized": 8
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "example",
                "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": "example, examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "example, examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-26T06:57:13.116492Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/ably/ably-java.svg",
  "full_name": "ably/ably-java",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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

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

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