Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-27 02:45 UTC

mikeller / subsurface

This is the official upstream of the Subsurface divelog program

C++GPL-2.0★ 0 stars⑂ 0 forkssince May 2021forkView on GitHub ↗

mikeller/subsurface holds a health index of 51 out of 100, placing it in the Moderate band. It scores highest on AI Readiness (82/100) and lowest on Community & Adoption (12/100). It was last updated today. 2 contributors account for most of its recent work.

51
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

51
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

Michael KellerPersonal account
267 followers55 public repossince Jun 2013

This repository is owned by a personal account. A single-owner project carries more continuity risk than an organization-backed one.

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

74Good · 22% of overall
How it's scored
36/36Push recency — last push 0 days ago
32.5/36Commit cadence — 47/52 weeks with commits
18/18Commit volume — 676 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year676
human_commit_share0.98
days_since_last_push0
active_weeks_last_year47
How it's scored
27/27Ships releases — 1 releases published
0/36Release recency — latest release 958 days ago
12.6/27Release cadence — cadence unknown (single release)
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Inputs used
releases_count1
latest_release_taglatest
releases_from_tagsno
days_since_latest_release958
mean_days_between_releases

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

12Critical · 18% of overall
How it's scored
0/60Stars — 0 stars
0/25Forks — 0 forks
0/15Watchers — 0 watchers
Inputs used
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
0/22.5README
22.5/22.5License — recognized license (GPL-2.0)
0/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeno
has_licenseno
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

56Moderate · 24% of overall
How it's scored
25.2/54Bus factor — 2 contributor(s) cover half of all commits
13.8/22.5Commit distribution — top contributor authored 39% of commits
13.5/13.5Contributor breadth — 98 contributors
10/10OpenSSF Scorecard: Contributors — project has 20 contributing companies or organizations
Inputs used
bus_factor2
contributors_sampled98
top_contributor_share0.387
How it's scored
0/46.8Issue resolution — no issues or no data
21.2/38.3PR acceptance — 5/9 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Inputs used
merged_prs5
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs4
Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
17.5/25Owner reach — 267 followers of mikeller
24.7/25Track record — 55 public repos, account ~13 yr old
Inputs used
followers267
owner_typeUser
is_verified
owner_loginmikeller
public_repos55
account_age_days4,785
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.

Engineering Quality

Are baseline engineering and documentation practices in place?

56Moderate · 20% of overall
How it's scored
24/24CI workflows — 24 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — no data
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.

Documentation

50Moderate
How it's scored
0/30README
25/25Documentation directory
15/15Documentation / homepage site — https://subsurface-divelog.org
0/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepagehttps://subsurface-divelog.org
has_readmeno
has_docs_diryes
has_descriptionno

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

51Moderate · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — no data
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 20 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — no data
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
5/5SAST — SAST tool detected: CodeQL
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate5.1
Excluded from scoring (no data or not applicable): ci_tests, packaging. Remaining weights renormalized.

AI Readiness

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.

82Good · 0% of overall
How it's scored
45/45Agent instructions — .github/copilot-instructions.md, CLAUDE.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 76 of 98 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.776
agent_instruction_files.github/copilot-instructions.md, CLAUDE.md
agent_instruction_max_bytes3,942
How it's scored
18/18One-command bootstrap — Documentation/Makefile, makefile
22/22Automated tests
0/11Lint / format config
11/11Static type checking — C++ (statically typed)
10/10Reproducible environment — Dockerfile
6/10Demonstrated agent practice — 3 of the last 100 commits agent-authored or agent-credited
8/8Automated maintenance — 2 of the last 100 commits are automated dependency updates
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfiles
has_dockerfileyes
typed_languageyes
bootstrap_filesDocumentation/Makefile, makefile
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0.03
toolchain_manifestsandroid-mobile/build.gradle
dependency_bot_commit_share0.02
How it's scored
45/45Type-checkable code — C++ (statically typed)
51.5/55Manageable file sizes — 41/653 source files over 60KB
Inputs used
primary_languageC++
largest_source_bytes667,032
source_files_sampled653
oversized_source_files41

Key facts

0GitHub stars
98contributors
676commits, last 12 months
0days since last push
1releases
2bus factor
0open issues
Mavenpackage ecosystems

Data collection warnings

  • Community profile unavailable
  • No resolved dependencies carried a version and a supported ecosystem

More detail

OpenSSF Scorecard 5.1 / 10
5.1aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-27 02:45 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/aCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
10Contributorsproject has 20 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate 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
n/aPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
10SASTSAST tool detected: CodeQL
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
All dependencies 2

Full resolved dependency set from the GitHub dependency graph: 0 direct and 2 indirect (transitive) packages. The transitive closure is complete when the repository commits a lockfile.

RegistryPackageVersionRelation
PyPIlaunchpadlibindirect
PyPIrequestsindirect
Dependency advisories not assessed

Advisory matching could not run for this report: No resolved dependencies carried a version and a supported ecosystem

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": true,
      "size_kb": 170616,
      "has_wiki": true,
      "homepage": "https://subsurface-divelog.org",
      "languages": {
        "C": 26312,
        "R": 4070,
        "C++": 4135007,
        "CSS": 7291,
        "QML": 332892,
        "TeX": 19220,
        "HTML": 39872,
        "Java": 20905,
        "Perl": 20679,
        "XSLT": 327107,
        "CMake": 111808,
        "Shell": 163933,
        "Python": 26629,
        "Makefile": 5192,
        "Dockerfile": 4303,
        "JavaScript": 98559,
        "PowerShell": 26362,
        "Objective-C++": 5639
      },
      "pushed_at": "2026-07-26T06:27:07Z",
      "created_at": "2021-05-14T22:58:09Z",
      "owner_type": "User",
      "updated_at": "2026-07-17T22:36:40Z",
      "description": "This is the official upstream of the Subsurface divelog program",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "GPL-2.0",
      "default_branch": "master",
      "license_spdx_raw": "GPL-2.0",
      "primary_language": "C++",
      "significant_languages": [
        "C++"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Michael Keller",
      "type": "User",
      "login": "mikeller",
      "company": null,
      "location": null,
      "followers": 267,
      "avatar_url": "https://avatars.githubusercontent.com/u/4742747?v=4",
      "created_at": "2013-06-19T22:31:31Z",
      "is_verified": null,
      "public_repos": 55,
      "account_age_days": 4785
    },
    "license": {
      "state": "standard",
      "spdx_id": "GPL-2.0",
      "raw_spdx": "GPL-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": false
    },
    "activity": {
      "releases": [
        {
          "tag": "latest",
          "kind": "other",
          "published_at": "2023-12-11T11:12:05Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "ba9b34ad239375cd8c971d88674d7df17bb2340b",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Windows: Update the instructions and scripts for MSVC. (#8)",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3128564018b5fb7458399dab2ba3cc29d077d769",
          "body": "Add a script that, given a release number, will list the pull request(s)\nthat were first released in this release.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Add a Script to Find Pull Requests Included in a Release. (#7)",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a47b423afb20d1e7dabdb4b31e304f21f37f814",
          "body": null,
          "is_bot": false,
          "headline": "Test android action changes.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7110ffec933f2e8781ebf8c90d34d1295ec1058",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix Workflow.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4112e175536fbf7b036d56fbdc0f77ee5a04317e",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Make workflows publish artifacts.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "379733886f3edcdc6f0f0f0f45f01d1cd3b3842e",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Revert to ubuntu 24.04.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "427a3d9c9f10277c9e8417234cf2517e4a94663e",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Add manual triggers to workflows for testing.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e44eff6da0b22c3b7cb426764493aaf83793ba22",
          "body": null,
          "is_bot": false,
          "headline": "Add Mako as a pip Package.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0d486a95dee8870908f56a87b97e86cc5db515d8",
          "body": "In support of #3954.\n\nAlso update MXE to the latest version.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Add libraw to the MXE build container.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c7f50dd2940be5e70a5c14b4f00d956e2de100a",
          "body": "In support of #3954.\n\nAlso update MXE to the latest version.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Add libraw to the MXE build container.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b89f010f25aafcdc22e18646a66c6202cd48e475",
          "body": "Signed-off-by: Michael Keller <mikeller@042.ch>",
          "is_bot": false,
          "headline": "Test GITHUB_SHA vs. github.sha.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd414d366aa2bc65f374eec90701d64fb40e6203",
          "body": null,
          "is_bot": false,
          "headline": "Test android action changes.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f498484cfd9994a3aad6df3b05a82d0f9d8163d",
          "body": "Signed-off-by: Michael Keller <michael.keller@canterbury.ac.nz>",
          "is_bot": false,
          "headline": "Update GitHub action to include signing.",
          "author_name": "Michael Keller",
          "author_login": "mikeller-uc",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5eb8e048454f7a6960740c6a675b7ddaad2eb4d3",
          "body": null,
          "is_bot": false,
          "headline": "Disable actions requiring authentication.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-17T22:36:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "51fed4624deee904309579d981cbbcce294bc054",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update libdivecomputer to latest on 'Subsurface-DS9'.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-15T19:47:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0061abfdf71a5e48d3c5e827db618e294045b596",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update libdivecomputer to latest on 'Subsurface-DS9'.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-15T19:47:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "744b8906d55bd36d949a9b3dabcf2313cc7608a3",
          "body": "Regenerated from the libdivecomputer descriptor after adding the\nShearwater Perdix 3, via scripts/update-supported-divecomputer-lists.sh.\n\nSigned-off-by: Vojtěch Šplíchal <splichal@gmail.com>",
          "is_bot": false,
          "headline": "Update the list of supported dive computers.",
          "author_name": "Vojtěch Šplíchal",
          "author_login": "splichy",
          "committed_at": "2026-07-15T19:47:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "adf28b1bd8fcb3611d4054add272e31ee26b2568",
          "body": "Point the submodule at the Perdix 3 BLE protocol support\n(splichy/subsurface-libdc @ 27c81c4).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nSigned-off-by: Vojtěch Šplíchal <splichal@gmail.com>",
          "is_bot": false,
          "headline": "Update libdivecomputer to latest on 'Subsurface-DS9'.",
          "author_name": "Vojtěch Šplíchal",
          "author_login": "splichy",
          "committed_at": "2026-07-15T19:47:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9a20396e1640f8bdddbbe3efac3aa39eebeb5ead",
          "body": "The Perdix 3 advertises a new vendor service instead of the classic\nShearwater serial service, so add its UUID to the preferred-service\ntable and add a \"Perdix 3\" name entry to the dive computer discovery\nlist (before \"Perdix\", since matching is by prefix).\n\nAdditionally, make the BLE connect on Lin\n[…]\nin libdivecomputer (the transport\nframing differs from the classic Shearwater BLE framing).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nSigned-off-by: Vojtěch Šplíchal <splichal@gmail.com>",
          "is_bot": false,
          "headline": "Add BLE support for the Shearwater Perdix 3",
          "author_name": "Vojtěch Šplíchal",
          "author_login": "splichy",
          "committed_at": "2026-07-15T19:47:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7590abccba290ddb1857250b232d910629490553",
          "body": "There are a few subtle problems if the BUILD_PREFIX is a relative path as it\nends up getting used from different working directories.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cleanup: the BUILD_PREFIX must be an absolute path",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93830db8169b5cb0f9347258dfca6543c4fbb44a",
          "body": "Let's have just one spot where we deal with the character sets and format that\nwe allow for email (aka Cloud user ID) and password.\n\nI'm aware that this adds QString to a core function. I consider this perfectly\nreasonable.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cleanup: share the email and password validation code",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "43f992a985e6801c34b3b6c1b21cffd1aeee2f28",
          "body": "Consolidate the definition into one place for all build types.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Cleanup the Definition of 'settings_suffix'.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca11ef2310e431c7b726b12b501dd675e950496a",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Add stub for 'Command::changesMade()' for the CLI.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "49ecc0aec55fc3f92eb4c500489054ad1c873a91",
          "body": "The refactoring to allow the profile export included a couple of bugs.\n\nAnd this also fixes some older bugs. Frankly, I don't understand why the\n'return NULL instead of std::string' bugs cause crashes when running the CLI on\ncertain versions of glibc, yet the full Subsurface seems to run just fine - but\nregardless, they clearly are bugs of the \"oh I'm so glad that C++ makes our\ncode so much better\" type.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "non-CLI build fixes",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "38a4939caf639ede635605e362fd06761244d094",
          "body": "For the initial usecase of the CLI this isn't needed, but when people build\nlibdivecomputer for 'normal' use in Subsurface (and not a stripped down version\nof it that drops libusb and libmtp from it), the CLI link step will fail\nwithout these dependencies included.\n\nThis seemed the smaller of two evils.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: build against libusb / libmtp",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "56814e2a56e35bf11ed34634baf5f12117106d6d",
          "body": "This is entirely created by Claude.\n\nIt takes advantage of the fact that using git storage as backend is actually\njust an implementation detail of the CLI - it simply uses parse_file() to open\na data source, so an XML file is just fine.\n\nThe list of tests and the test data need to be manually review\n[…]\n the code, so I'm comfortable signing off on it. But I don't\nclaim that I wrote this.\n\nCreated-by: Claude (a couple of minor edits / corrections from me)\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: add test harness",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "411a791785c2b94ad18c55aeee7b060157a03ba9",
          "body": "Also remove some debugging output.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: allow /tmp on macOS",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3984baacaf0d21ff94efad473cd5483eb1f8546f",
          "body": "This requires a fair bit of ifdef-hell in the shared backend / profile code,\nbut it does seem \"clean enough\" to make it worth while...\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: implement dive profile export",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "849b0f15b37fae27e4954b9aa61393c07042a882",
          "body": "Signed-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: show Oxygen as O2 instead of EAN100",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "962a56703c007f71d9cd828fa2abdbff0a5fa24c",
          "body": "While dives are named based on the time stamp, trips include the name or\nlocation, and that could introduce refs that weren't valid URLs and that would\nbreak the UI.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: ensure trip slugs are valid URLs",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c407745feacc0879f65bbbe32609e77e588a6ee",
          "body": "Those require the branch as part of the spec - so we need to update the\nvalidation as well.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: deal with bare repos on the server",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf94396c571c563ac78a4b8c83a64f6d1cb17fc7",
          "body": "We moved the config path into a systemd created / controlled path, but that\nwasn't allowed by the CLI.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: sync the hardening with webUI changes",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "571e8e1da89218f42d84978167dd29bb16864a21",
          "body": "Signed-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: reduce unnecessary dependencies",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "569acb05d4bfaef9a4c5a7d8a12ebf3c9aed5eec",
          "body": "Also prune back some of the stuff that goes in the core library by default to\nreduce the dependencies that we need.\n\nThis still includes way too much code that we really don't need, but it's a\nstart.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: setup cli build similar to other targets",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8949eef4f03e95a88e87ec451c63a5c2ec3cb18d",
          "body": "This should only be called from a trusted user or from the Flask webUI, so we\nshould expect save user input, but it never hurts to be careful...\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: some hardening and input validations",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4631dbdd152630a28ff585545abebbbaf661d35e",
          "body": "Signed-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: include tags in the dive summary structure",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0136da929e4414dfb4484c5f5462206d75a1de51",
          "body": "We needed to fix up the dive data from the dive computers to get the start and\nend pressures.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: correctly show cylinder info",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dbbf1b67e921d0ace144cdae6bd263ff7356c6ba",
          "body": "This gets us the dive list and allows us to retrieve trip and dive details.\n\nThis was implemented with some support from Claude Code. All code has been\ncarefully reviewed and tested.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cli: initial implementation of the subsurface-cli",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-07-15T11:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "898ef10f00334cca146deb965f710ad6ae9d6f4b",
          "body": "Update calculate_airuse() to skip cylinders marked as NOT_USED\n\nThis prevents SAC from being inflated by unused partner tanks or linked\nsensor tanks that are not actually breathed.\n\nAdds a regression test that verifies SAC stays unchanged when a second\ncylinder is marked as NOT_USED.\n\nget_errors shows no syntax issues in the updated files.\n\nSigned-off-by: Alex Cline <alex.cline@gmail.com>\nSigned-off-by: Alex Cline <400773+AlexCline@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Update SAC calculation to ignore NOT_USED cylinders",
          "author_name": "Alex Cline",
          "author_login": "AlexCline",
          "committed_at": "2026-07-14T20:04:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "80d4371738e840190a25d179c5d49154455f1ab3",
          "body": "Fix the Bluetooth classic support under linux that was broken in #4865.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Linux: Fix Bluetooth Classic Support.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-14T09:23:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "37deb3048933940c00b2de429862572e07b6e371",
          "body": "Add an option to force Bluetooth Classic without falling back to BLE.\nThis can be achieved by using a 'BT:' prefix to a Bluetooth address in\nthe same way 'LE:' forces BLE.\nThis can be used in cases where it is known that BLE will not succed\nwith the import / firmware upload.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Import: Add Option to Force Bluetooth Classic.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-13T05:37:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba33668fb48b8c75229314ad14c8d4d2996f09ad",
          "body": "…Models.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Add Tests for the DivePlannerModel to Verify it Is Working for Empty …",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-11T23:10:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f07bb88f6a2d458f814a9444726cd07f721eb11",
          "body": "Fix a crash when opening the Preferences dialog after scrolling to the\nend of the dive list with the Down key and scrolling one past the end.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Desktop: Fix Crash when Opening Preferences.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-11T23:10:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5cf7b75671b52bee8623b65b88b4a96d4933cf70",
          "body": "Show the dive computer supplied timezone offset information (if it\nexists) in the read only 'Date' field on the 'Dive Computer Info' tab.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Add the timezone information to the dive computer date field.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-10T06:20:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0de1d2602d02488f3c1618721a167c15e17ccb9b",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update Tests to Include the 'timezone offset' Extra Info Field.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-10T06:20:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dfaa5140c7fa6ac87ef35ffeff9b4da326cee7df",
          "body": "Add an 'Extra Info' field to show the timezone offset in seconds for\ndive computers that supply this information.\nEssentially a 'cut out the middleman' for\nhttps://github.com/subsurface/libdc/pull/100.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Add the Timezone Offset to Extra Info.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-10T06:20:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58fce938a02c6c871261584e56757e54b5ae6d1e",
          "body": "…al Number.\n\nOnly use '(no serial) #x' when there is a need to disambiguate.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Desktop: Don't Show '(no serial)' when there is no Dive Computer Seri…",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-10T06:15:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eaca753bfee13cd74d3faa1788fbd486d6808905",
          "body": "mikeller pointed out in review that the .json/.fit pairing logic added\nfor the Suunto Ocean gas-mix fix lived in mainwindow.cpp, even though\nit is entirely Suunto-specific. Move the SuuntoPair struct and the\npairing/reading loop into core/import-suunto-json.cpp as a new\nsuunto_json_fit_pair_import()\n[…]\ns local encodeFileName() helper.\nVerified with the existing and new Suunto test cases in testparse.cpp,\nall of which still pass.\n\nSigned-off-by: Holger <66156154+Lichtbringer@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Import: move Suunto .json/.fit pairing out of mainwindow.cpp",
          "author_name": "Holger",
          "author_login": "Lichtbringer",
          "committed_at": "2026-07-09T00:03:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3f64f4b67285f35934ca54017533312eaa00f1b7",
          "body": "suunto_json_import() is only declared for !SUBSURFACE_MOBILE (see\ncore/file.h), since it isn't available on mobile builds. The two new\ntests called it directly to exercise the new fit_buffer parameter, but\nonly wrapped the QSKIP() in \"#if defined(SUBSURFACE_MOBILE)\" - QSKIP\nonly skips at runtime, so\n[…]\n whole test body in #if !defined(SUBSURFACE_MOBILE) instead,\nmatching how the rest of the codebase guards uses of this function.\n\nSigned-off-by: Holger <66156154+Lichtbringer@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Import: Fix Suunto JSON test build on mobile",
          "author_name": "Holger",
          "author_login": "Lichtbringer",
          "committed_at": "2026-07-09T00:03:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3a6ddcbd4e52029de021c51309f4ff697eeb1709",
          "body": "The Windows (MXE/MinGW-w64) CI job builds with -Werror=format, and its\nlibc's printf format checking does not recognize %zu the way MSVC and\nglibc do, so the multi-gas warning added in the previous commit failed\nto compile there (\"unknown conversion type character 'z'\"). Cast the\nsize_t to unsigned \n[…]\natching the cast-to-a-plain-int\npattern already used elsewhere in this codebase for the same\ncross-toolchain portability reason.\n\nSigned-off-by: Holger <66156154+Lichtbringer@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Import: Fix Suunto JSON build error on MinGW-w64",
          "author_name": "Holger",
          "author_login": "Lichtbringer",
          "committed_at": "2026-07-09T00:03:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f050f14dda19e2371610c5458ccf8a9762843de2",
          "body": "The Suunto app's JSON export has no Diving.Gases block for the Ocean,\nso suunto_json_import() always fell back to a generic/air gas mix,\neven for a real Nitrox dive. Verified against a real user export: the\nJSON truly has no gas-mix data anywhere, but the .fit file the app\nexports alongside it (same\n[…]\nMulti-gas reconciliation between the JSON's\ngas-switch-order indexing and the FIT's native gas ordering is left\nfor a follow-up.\n\nSigned-off-by: Holger <66156154+Lichtbringer@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Import: Recover Suunto Ocean gas mix from paired FIT file",
          "author_name": "Holger",
          "author_login": "Lichtbringer",
          "committed_at": "2026-07-09T00:03:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "822eaab6a4a43f311c0c9fce1261d024cdd93003",
          "body": "If multiple dive computers were used in a dive, allow the user to select\nthe dive computer (and possibly serial number\nif multiple identical dive computers were used) in the 'Dive Computer\nInfo' tab. This will change the dive computer in an identical way to how\nit can be changed by using 'left arrow' and 'right arrow' in the dive\nprofile.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Desktop: Allow Dive Computer Selection in the Info Tab.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-08T12:47:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "de06e16d0e980168c7b37df44ff507e7c6fccfd4",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Use CMAKE_INSTALL_PREFIX directly.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-08T12:44:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fc14276a1bcb463f35bbbc4f38b1e67224a088f",
          "body": "Fix paths in CMakeFile.txt so that they work when building\nwith a repository clone that is symlinked from the build\ndirectory.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix CMakeFile.txt Paths for Symlink-based Builds.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-08T12:44:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b9396c2f8cbbfcd121c4066131f08f33dcd17c23",
          "body": "Add support for specifying a bluetooth device in the downloader.\nAlso clean up the execution loop for the OSTC firmware uploader.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Downloader: Add Support for Bluetooth",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-08T12:43:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8484c216c3182b7b8453723e94cdb0300de0e9b1",
          "body": "Garmin dive computers support up to 8 wireless tank pressure\nsensors, which 4 does not accommodate. Increase MAX_SENSORS to 10\nto provide headroom for the widest known current hardware.\n\nSigned-off-by: Ben Doherty <ben@notionparallax.co.uk>",
          "is_bot": false,
          "headline": "Core: increase MAX_SENSORS further to 10",
          "author_name": "Ben Doherty",
          "author_login": "notionparallax",
          "committed_at": "2026-07-07T07:28:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f90c966c6a3b10e32df11bb451c03baada20d24",
          "body": "The struct sample supports two tank pressure sensor slots,\noriginally designed for a main gas sensor and a CCR O2 supply\nsensor. This is documented in the comment on the pressure array\nin core/sample.h. The limit is enforced in add_sample_pressure()\nin core/sample.cpp, which silently discards data w\n[…]\nure4. Files\nsaved with more sensors degrade gracefully when opened by older\nbuilds, which will silently discard slots beyond index 1.\n\nFixes #4856\nSigned-off-by: Ben Doherty <ben@notionparallax.co.uk>",
          "is_bot": false,
          "headline": "Core: increase MAX_SENSORS from 2 to 4",
          "author_name": "Ben Doherty",
          "author_login": "notionparallax",
          "committed_at": "2026-07-07T07:28:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fa761d337841cf44ed6e0ba549cc7befbe1bcef3",
          "body": "Two independent issues in the native Windows/MSVC build path, both\nfound while building and testing an unrelated feature on a real MSVC\nsetup:\n\ncmake/Modules/version.cmake invoked \"powershell -File get-version.ps1\"\nwithout -NoProfile. If the user's PowerShell $PROFILE script writes\nanything to stdou\n[…]\nated\ncmake_install.cmake, \"\\v\" in \"C:\\vcpkg\" is read as an invalid escape\nsequence, failing \"ninja install\" with a syntax error.\n\nSigned-off-by: Holger <66156154+Lichtbringer@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Windows: Fix version and vcpkg path bugs in MSVC build scripts",
          "author_name": "Holger",
          "author_login": "Lichtbringer",
          "committed_at": "2026-07-07T07:27:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e35426ecd7ee8de27896c46079664d3693a7bebd",
          "body": "Manually copy the Qt dlls into the installation directory and then check\nthat they are present, to work around the fact that windeployqt fails\nsilently if it can't find a not needed dll.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Windows-MSVC: Manually Copy the Qt Dlls.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-06T02:02:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f69f2728a1f85d4197da59d8ab4ed09e07305c57",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Improve the Script to Find Pull Requests for a Release.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-05T20:54:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe30ae1e30823ad390f2a16dae1012eee22fbced",
          "body": "Fix some potential null pointer exceptions in the upload to divelogs.de\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Desktop: Fix Null Pointer Exceptions in divelogs.de upload.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-05T20:54:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b752107b1a042719c67195445e6ed4a53304ebf",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update libdivecomputer to latest on 'Subsurface-DS9'.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-02T12:33:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "87468c9768c25850552473c75d35164093772867",
          "body": "Update the instructions and scripts to work with Visual Studio 2026,\nsince the free Community edition of 2022 is no longer supported.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Windows: Update the instructions and scripts for MSVC.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-07-02T12:33:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "81d08a24784b3a062b005f24dd1da3744f929ec6",
          "body": "Add a script that, given a release number, will list the pull request(s)\nthat were first released in this release.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Add a Script to Find Pull Requests Included in a Release.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-30T08:31:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0d8e1d5f15261a1958fa1fd0d90e2c012f47819",
          "body": "Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.\n- [Release notes](https://github.com/actions/cache/releases)\n- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)\n- [Commits](https://github.com/actions/cache/compare/v5...v6)\n\n---\nupdated-dependencies:\n- dependency-name: actions/cache\n  dependency-version: '6'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump actions/cache from 5 to 6",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-30T03:09:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4e339f7b8285fb00748bc9be8bf5c2cabac5bb80",
          "body": "This is once again 'copied' from libdc.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "add model patterns for newer Pelagic dive computers",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-06-29T05:38:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "09da014a716bcf24657559a449ea8250c65673cf",
          "body": "…ynthetic rows\n\nChecking index.row() <= 1 to distinguish synthetic from real dive sites is\nfragile: the autocomplete row (source row 1) is filtered out when there is no\nautocomplete candidate or the typed text is an exact site name match, shifting\nreal sites into position 1 and causing a duplicate s\n[…]\nThe model already returns nullptr for synthetic rows and a real pointer for\nexisting sites, so ds encodes the intent correctly without any position check.\n\nSigned-off-by: chaehni <chaehni@outlook.com>",
          "is_bot": false,
          "headline": "fix(location): use ds pointer directly in itemActivated to identify s…",
          "author_name": "chaehni",
          "author_login": "chaehni",
          "committed_at": "2026-06-25T01:34:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4146679608ff8e7ff1f0dbeaa92688e6984f8bc6",
          "body": "Instead of using format-number for all numbers that could possibly have decimals to prevent commas when converting to json, we set the user's locale for numbers to \"C\" in order to use the minimal locale. This makes the conversion more robust against future changes to the exported format.\n\nSigned-off-by: Victor Arvidsson <victarv@gmail.com>",
          "is_bot": false,
          "headline": "Make conversion to json more robust against different locales.",
          "author_name": "Victor Arvidsson",
          "author_login": "vigge93",
          "committed_at": "2026-06-25T01:10:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf3d4748f9de438fa4221a201b571df66efc8aa6",
          "body": "…erged.\n\npost-releasenotes.yml now posts a one-shot comment on the PR that\ntriggered the push, linking to the draft release in nightly-builds.\nThe release URL becomes live once publish-release.yml flips draft to\npublished.\n\ncreate-releasenotes.sh: also writes release_pr_number.txt when a PR\nmatches the merge SHA, so the workflow step can comment without a\nsecond gh pr list call.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Comment \"First appeared in release vX.\" on Pull Requests when M…",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-23T06:30:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "577b48ccbcfcf119e20dbbec8c21a55d4799b90c",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/v6...v7)\n\n---\nupdated-dependenc\n[…]\n:\n- dependency-name: actions/checkout\n  dependency-version: '7'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump actions/checkout from 6 to 7",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-23T04:46:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2255f2877a276a07f75e7f4d672abffbd1ccad30",
          "body": "Add synthesised device creation for Qt6 for devices that do not advertise, and add retries for enabling notifications.\nAlso add some more logging when things go wrong.\n\nFixes #4840.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Android: Fix BLE Unreliability when Connecting.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-19T08:10:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "788aae13974e6b4e34bdc45a6cc2c88e17f8c527",
          "body": "This is one way to address the mismatch between the desktop UI\nshowing 'Fresh water' but calculating using seawater salinity when\ninitially opening plan mode.\n\nSigned-off-by: Christopher Blewett <chroblewett@gmail.com>",
          "is_bot": false,
          "headline": "fix(plan): Show 'Sea water' on plan mode init to match defaults",
          "author_name": "Christopher Blewett",
          "author_login": "chroblewett",
          "committed_at": "2026-06-19T07:57:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68f9e088803aca88efcefc6127a6e73d582aa898",
          "body": "Ensures that the \"Collapse others\" menu action on a trip keeps\nthe trip with the selected dive open. Previously, it was\ncollapsing all of them.\n\nReported-by: Kim Delmar\nSigned-off-by: Christopher Blewett <chroblewett@gmail.com>",
          "is_bot": false,
          "headline": "fix(divelist): Prevent 'Collapse others' from collapsing all",
          "author_name": "Christopher Blewett",
          "author_login": "chroblewett",
          "committed_at": "2026-06-18T22:47:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2af7016d3bfb73b2651dbed2c775f5289825ebd9",
          "body": "Add support for more generic html print templates that were supported in Qt5 but fail to print in Qt6.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Add more generic support for legacy / Qt5 template printing in Qt6.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-05T05:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7ad03cc5e912f6bb34f47d3b52403caddd5c9546",
          "body": "Simplify the code for generating print previews by introducing separate\ncode paths for QtWebView (Qt5) and QLiteHtml (Qt6).\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Separate code paths for QtWebView / QLiteHtml for print previews.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-05T05:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db40c4dd5a2c7c38228a1eb5273db4945355a38f",
          "body": "Fix printing support for templates valid in Qt5 and then re-enable the\ntests broken by the switch to Qt6.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix Printing and Re-enable the Tests.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-05T05:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "17ff7527c3887a8a6a623937d20499a7ca6c8f83",
          "body": "Do not require `-build-with-webkit` to include printing support when\nbuilding with Qt6.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix building with printing.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-05T05:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da950c1f414929941c03cf9adb9c45db46b757d9",
          "body": "Fix the warning happening in a test build (tested under linux).\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix Warnings in Test Build.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-05T04:57:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b95f74026eace7f9b0d5bfc67a7718da1b57237",
          "body": "Fix some warnings in the (linux) build.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix Build Warnings.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-05T04:57:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c99253d5a33aa30dc559eb88f877ee0f179ddda9",
          "body": "Wrap each dput invocation in a small retry loop with linear backoff\n(up to 5 attempts, 30s/60s/90s/120s between tries) so that transient\nLaunchpad hiccups no longer turn the workflow red. The end-of-loop\n'fail if anything is still broken' behaviour is preserved.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Retry Launchpad dput Uploads on Transient Failures.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-03T22:24:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e55a179c2d4011f194f9207c62971dbe8aa3d59f",
          "body": "Fix a potential use-after-free error in the dive computer firmware\nuploader.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Fix Potential Use-after-free Error in Firmware Uploader",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-03T11:42:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fab79c9b2ccf3cca709d8f58daf8ed6f8eefbc81",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update libdivecomputer to latest on 'Subsurface-DS9'.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-03T00:52:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5dedfcb0adcccdb6c7d6af9fb790e52ea4fec655",
          "body": "Use pre-evaluated variables for input parameters in the\n`notify-release-coordinator.yml` to remove the risk of shell string\ninterpolation being used as an attack vector.\n\nFixes the vulnerability alerted in #4830.\n\nReported-by: meimei wang <miemiewang22@gmail.com>\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Fix Input Interpolation Vulnerability.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-06-02T22:00:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40a53ede6c5df0fa8d69e6a9906133a206109da2",
          "body": "We seem to be getting mostly random errors when uploading to Launchpad.\nAt least try all of them instead of just giving up on the first failure.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "launchpad: don't give up on first error",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-22T20:03:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1cbc498ee28501153cb4f660d15acb2d561aa000",
          "body": "Persist the serial number and firmware version in Extra Data when\nimporting from Suunto JSON files.\n\nFixes #4813.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Import: Fix Serial Number / Firmware for Suunto JSON.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-05-22T04:25:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65e201f4f1c0f9cbb33e309955bd831e190ebed5",
          "body": "Fix the permissions requested by the `notify-release-coordinator`\nworkflow.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Fix the Workflow Permissions.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-05-22T03:58:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "75a70d7337f2abd2154c036a63b13330cd2c3298",
          "body": "That became obvious only after the previous commit was merged...\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cleanup: fix inherited GitHub Action permissions",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-22T02:20:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3c324fa755835f7b0df6c83fd2242e5b9cd9a00",
          "body": "I ended up asking Claude to help me fix it because I couldn't make sense of the\nerror (internal server error on Launchpad... that's... useful).\nI reviewed the changes and they make sense to me.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "launchpad: try to fix the GitHub action uploading builds",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-21T23:26:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ca9d447b08bfafb88436ec4a6371c0c34fceb6c2",
          "body": "Update the Windows runner for the MSVC build to match the lates runner\nname used by GitHub.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "CICD: Update the Windows Runner.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-05-21T22:12:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07d3211f7842b4a4dce5d3abb0588df9742d05b1",
          "body": "This is one of many OpenSSF recommendations for repository safety best\npractices.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cleanup: explicit permissions for GitHub Actions",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-20T16:51:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8917022b541076e4f0ed443858fddd559145f08f",
          "body": "These are recommended by the gradle problems-report.html.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "Android: updates for gradle 10 and latest SDK",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-20T12:11:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b1260c8cd28a66f8f418a6ebe1375e05a94264bd",
          "body": "Signed-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "update build and best practices badges in README",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-20T12:06:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4ca21aeb535ac230002fd9c398859930f0c4f1ac",
          "body": "Even though we have that try/catch block, we still get plenty of crashes\nfrom unsatisfied link errors for setUsbDevice(). I asked Claude to come\nup with something that has a higher likelihood of succeeding. This revision\nhas a broader set of errors that it catches and also works around a subtle\nlogi\n[…]\nh, but\nthe crash reports on Google Play are very specific about the stack trace\nand about the fact that they are from a version that includes this code.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "Android: try harder not to crash",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-16T18:25:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0ba64ab394d5c70245c2f1a0c0c7869e4c27ddf7",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update libdivecomputer to latest on 'Subsurface-DS9'.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-05-15T19:28:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "76388b14d6f3d0eadf9c79914997878edad0d3ef",
          "body": "For some reason the import of compass bearings for DiveSoft dive\ncomputers seems to be missing now.\n\nSigned-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update Tests to Match the libdivecomputer Changes.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-05-15T19:03:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61d0f973f28d27d40aa7bca9b3140a394d0a9169",
          "body": "Signed-off-by: Michael Keller <github@ike.ch>",
          "is_bot": false,
          "headline": "Update libdivecomputer to Latest in Upstream.",
          "author_name": "Michael Keller",
          "author_login": "mikeller",
          "committed_at": "2026-05-15T19:03:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8de4a22eafd5249564a1828b1c21225f8a37da5",
          "body": "These should comply with the Flathub requirements.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "metainfo: update screenshots",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-14T15:27:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e3b7f0a23d5df36d8b82f85989b8f6ed67ca76e",
          "body": "This the icon has better contrast both in light and dark theme.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "metainfo: slightly darken brand colors",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-14T15:27:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "de5df30ba767df65246c5cde136e5b340fd9ba8f",
          "body": "Screen size makes a huge difference - if the OS doesn't give us a default font\nsize, then pick something that is likely to work (the user can always change\nit).\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "desktop: attempt to pick a reasonable default font size",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-14T15:27:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a695144f629484664aa35b3d63104a25e32a2fc7",
          "body": "The filesystem layout is different - but things are configured to find\nthe shared object, so no point in warning.\n\nSigned-off-by: Dirk Hohndel <dirk@hohndel.org>",
          "is_bot": false,
          "headline": "cleanup: don't give pointless warning for flathub builds",
          "author_name": "Dirk Hohndel",
          "author_login": "dirkhh",
          "committed_at": "2026-05-14T15:27:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 1,
      "commits_last_year": 676,
      "latest_release_at": "2023-12-11T11:12:05Z",
      "latest_release_tag": "latest",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 47,
      "days_since_latest_release": 958,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": false,
      "has_license": false,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": null,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Documentation/Makefile",
        "makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "android-mobile/build.gradle"
      ],
      "largest_source_bytes": 667032,
      "source_files_sampled": 653,
      "oversized_source_files": 41,
      "agent_instruction_files": [
        ".github/copilot-instructions.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 3942
    },
    "dependencies": {
      "manifests": [
        "android-mobile/build.gradle"
      ],
      "advisories": {
        "error": "No resolved dependencies carried a version and a supported ecosystem",
        "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": 2,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "maven"
      ],
      "dependencies": [],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "launchpadlib",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 2,
        "direct_count": 0,
        "indirect_count": 2
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 5,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 4
      },
      "bus_factor": 2,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "dirkhh",
          "commits": 7362,
          "avatar_url": "https://avatars.githubusercontent.com/u/237471?v=4"
        },
        {
          "type": "User",
          "login": "bstoeger",
          "commits": 2882,
          "avatar_url": "https://avatars.githubusercontent.com/u/32835590?v=4"
        },
        {
          "type": "User",
          "login": "mturkia",
          "commits": 1033,
          "avatar_url": "https://avatars.githubusercontent.com/u/2674500?v=4"
        },
        {
          "type": "User",
          "login": "torvalds",
          "commits": 1011,
          "avatar_url": "https://avatars.githubusercontent.com/u/1024025?v=4"
        },
        {
          "type": "User",
          "login": "neolit123",
          "commits": 810,
          "avatar_url": "https://avatars.githubusercontent.com/u/331852?v=4"
        },
        {
          "type": "User",
          "login": "janiversen",
          "commits": 673,
          "avatar_url": "https://avatars.githubusercontent.com/u/6185391?v=4"
        },
        {
          "type": "User",
          "login": "glance-",
          "commits": 648,
          "avatar_url": "https://avatars.githubusercontent.com/u/1290022?v=4"
        },
        {
          "type": "User",
          "login": "atdotde",
          "commits": 636,
          "avatar_url": "https://avatars.githubusercontent.com/u/863957?v=4"
        },
        {
          "type": "User",
          "login": "mikeller",
          "commits": 549,
          "avatar_url": "https://avatars.githubusercontent.com/u/4742747?v=4"
        },
        {
          "type": "User",
          "login": "janmulder",
          "commits": 438,
          "avatar_url": "https://avatars.githubusercontent.com/u/12073956?v=4"
        }
      ],
      "contributors_sampled": 98,
      "top_contributor_share": 0.387
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "android-dockerimage.yml",
        "android.yml",
        "artifact-links.yml",
        "check-divecomputer-lists.yml",
        "claude-review.yml",
        "codeql-analysis.yml",
        "detect_merge_conflicts.yml",
        "documentation-build.yml",
        "documentation-publish.yml",
        "ios.yml",
        "linux-debian-generic-qt6.yml",
        "linux-debian-generic.yml",
        "linux-debian-ubuntu-matrix.yml",
        "linux-fedora-qt6.yml",
        "linux-snap.yml",
        "linux-ubuntu-20.04-qt5-appimage.yml",
        "linux-ubuntu-24.04-qt5-export-html.yml",
        "mac.yml",
        "notify-release-coordinator.yml",
        "post-releasenotes.yml",
        "publish-release.yml",
        "windows-msvc-qt6.yml",
        "windows-mxe-dockerimage.yml",
        "windows.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 20 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": 10,
            "reason": "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": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 10,
            "reason": "SAST tool detected: CodeQL",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "ba9b34ad239375cd8c971d88674d7df17bb2340b",
        "ran_at": "2026-07-27T02:45:03Z",
        "aggregate_score": 5.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": true,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-25T03:22:39Z",
      "oldest_open_prs": [
        {
          "number": 9,
          "created_at": "2026-07-02T23:33:45Z",
          "last_comment_at": "2026-07-17T22:38:45Z",
          "last_comment_author": "github-actions"
        },
        {
          "number": 14,
          "created_at": "2026-07-17T22:36:58Z",
          "last_comment_at": "2026-07-18T21:44:11Z",
          "last_comment_author": "coderabbitai"
        }
      ],
      "last_merged_pr_at": "2026-07-13T05:32:28Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/mikeller/subsurface",
    "host": "github.com",
    "name": "subsurface",
    "owner": "mikeller"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 51,
      "inputs": {
        "security": 51,
        "vitality": 74,
        "community": 12,
        "governance": 56,
        "engineering": 56
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 74,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 96,
            "inputs": {
              "commits_last_year": 676,
              "human_commit_share": 0.98,
              "days_since_last_push": 0,
              "active_weeks_last_year": 47
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "47/52 weeks with commits",
                "points": 32.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 47
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "676 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 676
                    }
                  }
                ],
                "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": "at_risk",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "releases_count": 1,
              "latest_release_tag": "latest",
              "releases_from_tags": false,
              "days_since_latest_release": 958,
              "mean_days_between_releases": null
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "1 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 958 days ago",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 958
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "cadence unknown (single release)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence_unknown",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "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": 9,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 9 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 9
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 12,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "critical",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 25,
            "inputs": {
              "has_readme": false,
              "has_license": false,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (GPL-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "GPL-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 56,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "moderate",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 62,
            "inputs": {
              "bus_factor": 2,
              "contributors_sampled": 98,
              "top_contributor_share": 0.387
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "2 contributor(s) cover half of all commits",
                "points": 25.2,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 39% of commits",
                "points": 13.8,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 39
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "98 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 98
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 20 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 40,
            "inputs": {
              "merged_prs": 5,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 4
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "5/9 decided PRs merged",
                "points": 21.2,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 5,
                      "decided": 9
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 65,
            "inputs": {
              "followers": 267,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "mikeller",
              "public_repos": 55,
              "account_age_days": 4785
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "267 followers of mikeller",
                "points": 17.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 267,
                      "login": "mikeller"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "55 public repos, account ~13 yr old",
                "points": 24.7,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 55
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 13
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 56,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "24 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 24
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://subsurface-divelog.org",
              "has_readme": false,
              "has_docs_dir": true,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://subsurface-divelog.org",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 51,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 51,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 5.1
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 20 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": "update tool detected",
                "points": 7.5,
                "status": "met",
                "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 not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool detected: CodeQL",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "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": 10
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 82,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.776,
              "agent_instruction_files": [
                ".github/copilot-instructions.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 3942
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".github/copilot-instructions.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".github/copilot-instructions.md, CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "76 of 98 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 76,
                      "sampled": 98
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [
                "Documentation/Makefile",
                "makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.03,
              "toolchain_manifests": [
                "android-mobile/build.gradle"
              ],
              "dependency_bot_commit_share": 0.02
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Documentation/Makefile, makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Documentation/Makefile, makefile"
                    }
                  }
                ],
                "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": "C++ (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "C++"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "3 of the last 100 commits agent-authored or agent-credited",
                "points": 6,
                "status": "partial",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 3,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "2 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 2,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 96,
            "inputs": {
              "primary_language": "C++",
              "largest_source_bytes": 667032,
              "source_files_sampled": 653,
              "oversized_source_files": 41
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "C++ (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "C++"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "41/653 source files over 60KB",
                "points": 51.5,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 653,
                      "oversized": 41
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Community profile unavailable",
    "No resolved dependencies carried a version and a supported ecosystem"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T02:45:24.571761Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/m/mikeller/subsurface.svg",
  "full_name": "mikeller/subsurface",
  "license_state": "standard",
  "license_spdx": "GPL-2.0"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statistics.