公开记录
软件健康报告模式 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年12月在 GitHub 上查看 ↗

ably/ably-java 的健康指数为 100 分中的 74 分,处于「良好」区间。 其得分最高的类别是Vitality(94/100),最低的是AI Readiness(58/100)。 最近一次更新在 4 天前。 近期的大部分工作由 3 位贡献者完成。

74
总分 / 100
良好

软件健康指数

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

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

评分画像

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

所有权

214 关注者123 个公开仓库始于 2012年6月

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

按类别列示的指标

活力

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

94优秀 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 4 天前
26.3/36提交节奏 — 52 周中有 38 周有提交
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

发布纪律

100优秀
评分方式
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

社区健康

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

可持续性与治理

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

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议题解决 — 75% 的议题已关闭
31.5/38.3PR 接受 — 已裁定的 PR 中 571/693 已合并
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所有者影响力 — ably 有 214 位关注者
25/25既往记录 — 123 个公开仓库,账户约 14 年
所用输入
followers214
owner_typeOrganization
is_verified
owner_loginably
public_repos123
account_age_days5,151

工程质量

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

70良好 · 占总体的 20%

工程实践

74良好
评分方式
24/24CI 工作流 — 7 个工作流
24/24存在测试
0/16Linter 配置
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。 其余权重已重新归一化。

AI 就绪度

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

58中等 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
34.7/40可读的提交历史 — 100 次人类提交中有 65 次说明了意图(结构化标题或解释性正文)
所用输入
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/11Lint / 格式化配置
11/11静态类型检查 — Java(静态类型)
0/10可复现环境
10/10已体现的代理实践 — 最近 100 次提交中有 8 次由代理编写或署名代理
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可控的文件大小 — 采样的 456 个源文件中有 8 个超过 60KB
所用输入
primary_languageJava
largest_source_bytes161,962
source_files_sampled456
oversized_source_files8

机器可读接口

40存在风险
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
0/20MCP 服务器
40/40可运行示例 — example, examples
所用输入
example_dirsexample, examples
has_mcp_signal
api_schema_files

关键数据

100GitHub 星标
38贡献者
280最近 12 个月提交数
4距最近推送天数
100发布版本数
3巴士系数(bus factor)
134开放议题
Maven软件包生态系统数

数据采集警告

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

更多细节

Star 与 Fork 历史 0 ★ / 45 ⇿
0Star
45Fork
99发布

每颗 star 和每个 fork 的添加时间,来自 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 个间接(传递)软件包。仓库提交锁文件时,传递闭包才是完整的。

注册表软件包版本关系
依赖安全公告 未评估

本报告未能完成公告比对: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—— 完整方法论 · 指标知识库.

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